View and edit multipage TIFFs with VB.NET

We have an example project for VB.NET that shows how to display and edit multipage TIFF files. Download the project code.

The demo uses the trial version of csXImage, which must must be registered on the development computer and the licence file must be in the same folder as the .ocx control. Running our installer will have performed the registration and unpacking of files.

When the VB form is loaded, and event runs to populate the combo boxes to request the number of pages to scan. This makes it easier to follow than setting the values in the VB IDE.

Here is a screenshot of the application after the form has loaded. It is simply a csXImage control in a form with some buttons to activate the different functions. These are enables and disabled as appropriate.

VB.NET project to view and edit multipage TIFF images

The csXImage control can only hold one image for display at any time so the method used to view multiple images is to store them in an array of variables of type Object. This array, as well as the total number of images and the current image, is declared globally.

Private Pages() As Object
Private ImageCount As Integer
Private CurrentImage As Integer

The code used to load the image contains several features worth noting. First, the image is selected by the user using the LoadDialog method. As only one page can be read by csXImage at any time, the first page is read by LoadDialog by setting ReadImageNumber to one. Then this first image is stored in the Pages array by exporting it from csXImage using WriteBinary and it is exported in bitmap format. Any format could have been used but bitmap has been chosen because it requires less processing than the compressed types, although it does require more memory.

The file selected by LoadDialog can be found by reading the LastFileName property. This is used to find the total number of pages in the image, using ImageCount. Now a loop can be formed to read each page in turn and write it to the Pages array variable. After completion of the loop, the first image is loaded into csXImage from the array, using the ReadBinary2 method.

Finally some buttons are enabled if there is at least 1 page and some more are enabled if there are multiple pages.

Note: Older versions of csXImage use the command ReadBinary which took an extra parameter to define the file format, although this parameter had become redundant as images were read regardles of the format. The command ReadBinary2 has been introduced for simplification.

Private Sub cmdLoad_Click(ByVal sender As System.Object, ByVal e
  As System.EventArgs) Handles cmdLoad.Click

  Dim i As Integer

  AxImageBox1.ReadImageNumber = 1
  AxImageBox1.LoadDialog()

  ReDim Pages(1)
  Pages(1) = AxImageBox1.WriteBinary(csXImageTrial.TxGraphicsFormat.gfBMP)
  ImageCount = AxImageBox1.ImageCount(AxImageBox1.LastFileName)
  If ImageCount > 1 Then
    ReDim Preserve Pages(ImageCount)
    For i = 2 To ImageCount
      AxImageBox1.ReadImageNumber = i
      AxImageBox1.LoadFromFile(AxImageBox1.LastFileName)
      Pages(i) = AxImageBox1.WriteBinary(csXImageTrial.TxGraphicsFormat.gfBMP)
      lblPageNumText.Text = "Loading - Page " & i & " of " & ImageCount
      Me.Refresh()
    Next i
  End If

  CurrentImage = 1   AxImageBox1.ReadBinary2(Pages(CurrentImage))
  lblPageNumText.Text = "Page " & CurrentImage & " of " & ImageCount

  If ImageCount > 0 Then

    cmdSave.Enabled = True
    cmdRotate90.Enabled = True
    cmdRotate180.Enabled = True
    cmdRotate270.Enabled = True
    cmdCrop.Enabled = True
    cmdDespeckle.Enabled = True

    If ImageCount > 1 Then
      cmdPrev.Enabled = True
      cmdNext.Enabled = True
    Else
      cmdPrev.Enabled = False
      cmdNext.Enabled = False
    End If

  End If

End Sub

Stepping forwards and backwards through the image is relatively simple. The new page is read from the Pages array using ReadBinary2 and the CurrentImage variable is updated.

Private Sub cmdNext_Click(ByVal sender As System.Object, ByVal e
    As System.EventArgs) Handles cmdNext.Click

  If CurrentImage < ImageCount Then
    CurrentImage = CurrentImage + 1
    AxImageBox1.ReadBinary2(Pages(CurrentImage))
    lblPageNumText.Text = "Page " & CurrentImage & " of " & ImageCount
  End If

End Sub

Private Sub cmdPrev_Click(ByVal sender As System.Object, ByVal e
    As System.EventArgs) Handles cmdPrev.Click

  If CurrentImage > 1 Then
    CurrentImage = CurrentImage - 1
    AxImageBox1.ReadBinary2(Pages(CurrentImage))
    lblPageNumText.Text = "Page " & CurrentImage & " of " & ImageCount
  End If

End Sub

We will leave the description of the scanning code because that is covered in the Twain Demo and the ADF Demo. The only significant difference is that in this example each scanned page is stored in the array variable.

To save the image, each page must be added to a multipage TIFF in the memory of csXImage using the AddToTIF method. Each image is loaded into csXImage in turn and AddToTIF is called. Any settings that apply to each page, such as Compression and ColorFormat must be set before calling AddToTIF. The WriteTIFDialog method is used so that the user can specify the location and name of the saved file. Finally the current image is loaded back into the control.

Private Sub cmdSave_Click(ByVal sender As System.Object, ByVal e
    As System.EventArgs) Handles cmdSave.Click

  Dim i As Integer

  For i = 1 To ImageCount
    AxImageBox1.ReadBinary2(Pages(i))
    lblPageNumText.Text = "Saving - Page " & CurrentImage & " of " & ImageCount
    If AxImageBox1.ColorFormat = csXImageTrial.TxColorFormat.cfMonoBW Then
      AxImageBox1.Compression = csXImageTrial.TxCompression.cmGroup4
    Else
      AxImageBox1.Compression = csXImageTrial.TxCompression.cmNone
    End If
    AxImageBox1.AddToTIF(0)
  Next i

  AxImageBox1.WriteTIFDialog()
  AxImageBox1.ReadBinary2(Pages(CurrentImage))
  lblPageNumText.Text = "Page " & CurrentImage & " of " & ImageCount

End Sub