Download THBImage image and vector viewing and processing SDK
Download THBImage image and vector viewing and processing SDK

THBImage Viewer is a small and fast raster picture and vector data viewer.
THBImage Viewer is a small and fast raster picture and vector data viewer.

THBImage 5.0 F.A.Q
THBImage 5.0 F.A.Q

How can I create Esri SHP files?

To write vector data like Shape files you need the THBVector object.
You can fill it with data either by loading existing vector files or by manually populating it with data.
Use the THBVector.SaveToFile method to write out the data. Shape files can consist of multiple files. The SHP file contains the geometry. The dbf file contains additional attributes for each geometry object and a SHX index file.
You can use the FileFormatSettings properties to affect which files are generated.

Vec.FileFormatSettings.SHPWriteDBase = TRUE;
Vec.FileFormatSettings.SHPWriteIndexFile = TRUE;
Vec.FileFormatSettings.SHPWriteLayer = "0";

How can I convert Esri SHP to DXF and DGN to DXF?

Use the THBVector object to load your shp file. Vec.LoadFromFile “c:\YourShape.shp”, thbvfSHP After loading you will have one layer in the THBVector object that contains the geometry.

If you set Vec.LoadFolder = TRUE; then all shp files of a folder will be loaded. Each file comes into a separate layer. You can access the layers through the THBVector object Vec.Layers

To write out dxf data call Vec.SaveToFile "C:\new.dxf", thbvfDXF All layers will be added to the dxf file.

Why are there small triangles across my vectordata?

The evaluation version of THBVector adds triangles to the data.

How can I remove the Zoom Buttons from THBView?

Use the THBView.UserInterface object to access and modify the buttons that THBView offers by default. You can remove existung buttons or add new ones.

THBView1.Scroll.Enabled = True
THBView1.UserInterface.Clear
THBView1.UserInterface.PageNavigation = False
THBView1.UserInterface.AddButton thbvbDrawCircle, thbcaBottom
THBView1.UserInterface.Recreate

How can I view pictures from the web?

The easiest way is to use THBImageEdit.LoadPictureFrom Url method. Or use the THBWebRequest object to get full control over all aspects of http and ftp access.

'Loading from http or ftp url using the webrequest object
'web.URL = "http://www.your.com/94425.jpg"
web.URL = "ftp://www.your.com/00094425.jpg"
web.Start
ie.LoadPictureFromMem2 web.DownloadedData, thbifAutoDetect

' Simplest way
'ie.LoadPictureFromUrl web, "http://www.your.com/94425.jpg", thbifAutoDetect, 0
ie.LoadPictureFromUrl web, "ftp://www.your.com/00094425.jpg", thbifAutoDetect, 0

How can I use secure ftp?

For password protected ftp use the Web.UserPwd property

UserPwd User and password [user name]:[password] to use for the connection. Use HttpAuthentication to decide authentication method.

When using NTLM, you can set domain by prepending it to the user name and separating the domain and name with a forward (/) or backward slash (). Like this: ‘domain/user:password’ or ‘domainuser:password’. Some HTTP servers (on Windows) support this style even for Basic authentication.

When using HTTP and FollowLocation, THBWebRequest might perform several requests to possibly different hosts. THBWebRequest will only send this user and password information to hosts using the initial host name (unless UnrestrictedAuthentication is set), so if THBWebRequest follows locations to other hosts it will not send the user and password to those. This is enforced to prevent accidental information leakage.

After loading the image and zooming in and out a few times vb crashes.

Vb displays an error message like this: Faulting application vb6.exe, version 6.0.81.76, faulting module thbvie50.dll, version 5.0.2.1, fault address 0x000838e2.

Please ensure that you prevent dll unloading. Vb simply unloads dlls athough they are still in use, which causes ugly exceptions. This is the most obvious cause of a crash.

' We have to keep the dlls alife therefore create objects
' that ensure that our dlls don't get unloaded
Public iestd As THBImageStandard
Public ie As THBImageEdit
Public view As THBViewLayer
Public vec As THBGeometry

Private Sub Form_Load()
    On Error GoTo ErrHandler
    
    Set iestd = New THBImageStandard
    Set ie = New THBImageEdit
    Set view = New THBViewLayer
    Set vec = New THBGeometry
    Exit Sub
ErrHandler:
    MsgBox Err.Description
End Sub

I’m using THBTwain 5.0 to control the twain scanner from Fujitsu fi-5120c. When I run a small test program with .Net C# on VS2005 to acquire the image from scanner everything is ok but when I exit the program and restart again then I get the error message like “Please check you scanner is connect the cable and power supply”. At this state other applications on PC can’t access the scanner it says “Other programs are using this scanner”. So I have to restart my PC again then it come to work again.

To solve this you can explicitly try to use the Close function and eventually EndSession function at end of scan function.

private void button1_Click(object sender, EventArgs e)
{
	THBImageTwain imgtwain = new THBImageTwain();
	THBTwain twain = imgtwain.InterfaceITHBTwain;
	twain.Init();
	twain.AppInfoSet(...);
	twain.SelectByType(false);
	twain.Open();
	try
	{
		twain.MsgNotify = true;
		twain.TwainModeModal = true;
		twain.AcquireFiles("e:\\Scanned.bmp", 
			thbDTWAIN_Filetransfer.thbDTWAIN_FF_BMP , 
			thbDTWAIN_FileAcquireFlags . thbDTWAIN_FAF_USENAME , 
			thbDTWAIN_PixelType.thbDTWAIN_PT_BW, 2, false, true);
	}
	catch (Exception ex)
	{
		MessageBox.Show(ex.Message);
	}
	finally
	{
		twain.Close();
		twain.EndSession();
		imgtwain.Dispose();
		imgtwain = null;
		twain = null;
	}
}

How can I scan tiff documents?

There are two ways to do this, either in modal mode where you scan all pages and then save the result using SaveAllAcquiredImages. Or in modeless mode (see frmTwainModeless) where you can process each page immediately after scanning. This is quite useful for larger scan jobs scanning 100 pages or so you can process each page immediately after scanning. You will get the AcquirePageDone event where you should append the scanned document to the existing multipage tiff file.

Private Sub twainevents_AcquirePageDone(plngReturn As Long)      
    On Error GoTo ErrHandler

	'Create an array large enough to store all pages
    Dim uf As New THBUtilsFactory
    Set arImages = uf.CreateTHBArrayObject
    arImages.Size = 1 

    'Fill the array with the acquired page
    Dim ie As THBImageEdit
    Set ie = imgtwain.CurrentAcquiredImage

    'Set PDF/TIFF export options
	If ie.BitsPerPixel = 1 Then
		'Export TIFF with CCITT Group4 Compression
		ie.FileFormatSettings.TIFFCompression = thbTIFFCompCCITTFAX4
		ie.FileFormatSettings.TIFFFaxMode = thbTIFFFaxModeClassF
		ie.FileFormatSettings.TIFFGroup4Options = thbTIFFGroup4None
	Else
		ie.FileFormatSettings.TIFFCompression = thbTIFFCompPACKBITS
	End If

	'Put it into the array
	arImages.At(0) = ie.InterfaceITHBObject
 
    'Save the multipage file
    bAppend = FileExists(strFileDst)
    Set ieSave = New THBImageEdit
    If bPDF Then
	ieSave.FileFormatSettings.PDFSettings "THBImage", _
	    Format(Now), _
	    "THBComponentware", "THBImage", _
	    strFileDst, strFileDst, "PDF, Picture"
	ieSave.SavePictureMultiToFile arImages, strFileDst, thbifPDF, bAppend
    Else
	ieSave.SavePictureMultiToFile arImages, strFileDst, thbifTIF, bAppend
    End If

    Exit Sub
ErrHandler:
    MsgBox Err.Description
End Sub

After drawing rectangle in the THBView, how to move the selected rectangle?

You can use the commands thbCmdMoveGeometry, thbCmdEditGeometry thbCmdRotateGeometry. To start a command use THBView.Commands.Start(thbCmdMoveGeometry) Now the user can move the selected geometry.

If you’d like to do this in your code you may go this way. Let the user select one geometry object. Now use THBView.SelectedLayer.All.GetAt(0).Translate(10, 10); To move the geometry 10 world units to the right and top. Sure you could do this in one line but you should secure some things

	THBGeometryList gl = thbView1.SelectedLayer.All;
	if(gl.Count != 1) return;
	gl.GetAt(0).Translate(10, 10);

This was quite easy. The more complicated part is to enforce a THBView redraw. THBView will just redraw anything if you set the layer to dirty within BeginUpdate and EndUpdate. So here is the complete code

			// get the first selected geometry
			THBGeometryList gl = thbView1.SelectedLayer.All;
			if(gl.Count != 1) return;
			vec_.BeginUpdate();
			// move the geometry
			gl.GetAt(0).Translate(10, 10);
			// set the layer dirty
			vec_.GetLayers().GetAtIndex(0).IsDirty = true;
			vec_.EndUpdate();
			// clear the selection
			thbView1.SelectedLayer.RemoveAll();
			thbView1.Redraw();

How can I set a picture on the Geometry?

The standard geometry objects can not display pictures or show tooltips, instead you need a THBRegionGeometry. It extends the capabilities of the basice point, line, polygon,… geometries.

To assign pictures to the THBRegion geometry you have two choices. You can either use an imagelist (read about imagelists in the docu) THBUtilsFactory uf = new THBUtilsFactory(); THBImageList imageList = uf.CreateTHBImageList(); imageList.Load… Now assign the pictures from the imagelist to the region object.

The second way is to create new pictures and assign them

THBUtilsFactory uf = new THBUtilsFactory();
THBImageStandard imagePin = uf.CreateTHBImageStandard();
THBImageStandard imagePinHigh = uf.CreateTHBImageStandard();
imagePin.LoadPictureFromFile(Utils.GetPictureDir() + "18.jpg", thbImgFormat.thbifAutoDetect);
imagePinHigh.LoadPictureFromFile(Utils.GetPictureDir() + "22.jpg", thbImgFormat.thbifAutoDetect);
geomregion.Picture = imagePin;
geomregion.PictureHighlighted = imagePinHigh;

I don’t know if I should use THB.THBImageLib.dll or THB.THBImageLib2005.dll version of the .Net dlls?

The THBImage.chm that comes along with the thbimg.zip THBImage5.0 setup contains a Deployment section that describes the files in detail. .Net assembly dlls are built against a .Net framework. There are 1.0 1.1 2.0 3.0 3.5 .Net frameworks available till now. THB.THBImageLib.dll was built against 1.1 THB.THBImageLib2005.dll was built against 2.0 2005 means Visual Studio 2005 here which comes with .Net2.0 by default. Now there is Visual Studio 2008 available too, maybe we add THB.THBImageLib2008.dll too. So depending on your preferred .Net Framework you an choose the assembly.

Is there a way to call the THBTwain.Select method so that it does not display a pop-up box?

You can use THBTwain.EnumSources which returns all available scanners. Then create your own listbox where you offer all twain devices to the user. Store the selected twain device in your applications settings and the next time you can choose the twain scanner by using THBTwain.SelectByName.

TVieAP50.dll not found

If you have troubles like TVieAP50.dll not found then there are three common problems:

  • a 32bit executeable tries to find 32bit dlls but just finds 64bit dlls
  • a 64bit executeable tries to find 64bit dlls but just finds 32bit dlls
  • MSVCRT90 runtime files folder is missing or MSVCRT90 setup was not installed(which is just necessary if there is no MSVCRT90 runtime files folder)
  • While using VisualStudio.NET you may get this message because VisualStudio.NET copies the THB.THBImage.dll .Net assembly from the bin32/All folder (or bin64/All respectively) into the projects output folder. As a consequence the native dlls like TVieAP50.dll are no longer in the same folder along with the .Net assembly THB.THBImage.dll.

To solve this please

  • Remove the binary folder that you don’t need (bin32/All or bin64/All).
  • The easiest way is to create a PATH environment variable pointing to the binary folder but this is an optional step.
  • Run the proper vcredist executeable. There are separate versions for 32bit and 64bit.
  • Set the CopyLocal property of the THB.THBImage.dll reference to False.
Native dlls like TVieAP50.dll have to be in the same folder along with the .Net assembly THB.THBImage.dll

Native dlls like TVieAP50.dll have to be in the same folder along with the .Net assembly THB.THBImage.dll

Each vcredist has a version number. Downloading any package from www.microsoft.com does not guarantee that you have the proper version. So you have to take the version that we deliver along with the THBImage SDK setup or take care that you download the proper version at www.microsoft.com.

How to deploy 32bit version

To deploy the 32bit version of THBImage please go to the bin32/All folder, run YourSetup.cmd and add all remaining files to your setup. Deploy all files to your application.exe folder.

How to deploy 64bit version

To deploy the 64bit version do the same in the bin64/All folder.

How can I create PDF files from TIFF?

The first way is to use the THBPdfDocumentPageWriter object. You find more PDFWriter examples in the THBImage.chm docu Main Classes->THBPDF->Getting Started

Another way to create pdf files from pictures is to use the THBImageEdit object directly.

ie.FileFormatSettings.PDFSettings "THBImage", _ Format(Now), _ "THBComponentware", "THBImage", _ strFileDst, strFileDst, "PDF, Picture" ie.SavePictureMultiToFile arImages, strFileDst, thbifPDF, bAppend

If you search for ‘SaveAllAcquiredImages’ in the demo projects you will find a complete example.

But the first step is always the same, it is loading the tiff file into a THBImageEdit object using LoadPictureFromFile.

So what’s the difference between these to techniques.
When using THBImageEdit to create PDF files you have to prepare an array of all pages of the file. This means you have to store all pages in memory before writing out the PDF file. Which works fine with files less then 10 pages but will cause an out of memory error with larger pdf documents.
Another limitation is that you can’t add additional PDF elements like text or Hyperlinks.

The second technique is to use the THBPdfDocumentPageWriter object.
Here you can add page by page, add additional PDF elements like text or hyperlink and write out the file when finished.
pdf.PageWriter.AddLayerImage(UtilsFactory.CreateTHBRectd(0,0,100,100), "Main", "Layer1", ie); pdf.PageWriter.AddLayerImage(UtilsFactory.CreateTHBRectd(0,0,100,200), "Main2", "Layer2", ie2); pdf.PageWriter.AddLayerImage(UtilsFactory.CreateTHBRectd(0,0,100,300), "Main3", "Layer3", ie3);

The code can be easily ported to Vb.Net, Vb6, C++

How can I convert PDF to TIFF using THBImage?

The THBPdfDocument object can read pdf files and extract the contained pictures and store them into a new picture files.
So we don’t render the pdf on our own, we just read out the pictures.
You can find some PDF examples in the docu at Main Classes -> THBPdf -> Getting Started

When I display the first image in my C# .NET application the mouse wheel zooming works correctly but when I display additional images the mouse wheel zooming fails.

The MouseWheel zooming just works if the focus is on the C# .NET THBView control. To enforce this use the Focus function. thbView1.Focus();

MouseWheel support for the .NET control was added in 5.0.5.6. It was always part of the ActiveX/Com version but not in the .Net version.

How can get a rectangle selection from the user and use it for imageprocessing filters?

One way is to let the user draw a rectangle.
The rectangle will never be stored in a vector layer, instead we just extract its coordinates after creation.

Here is a complete VB.NET Windows Forms demo using THBImage to get the selection from the user. crop.zip

' let the user draw a rectangle ThbView1.Commands.Start(thbCommand.thbCmdRect)

After drawing it we get the NewGeometry event

In the previous THBImage version this event was called NewRegion. Starting from THBImage 5.0 vector objects are called geometry objects.

The new rectangle geometry object will be passed to this event and we have the option to either store it within a THBVector layer for viewing or to simply extract its parameters.

Private Sub ThbView1_EventNewGeometry(ByVal geometry As THB.THBGeometry) Handles ThbView1.EventNewGeometry
	Try
	    Crop(geometry)
	Catch ex As Exception
	    MsgBox(ex.Message)
	End Try
End Sub

This simple example extracts the rectangle bounds and crops out the rectangle part of the image.
Here we assume that you added a picture layer before.

Dim rcBounds As THBRectd
Dim rcBoundsPixel As THBRect

'We need a rectangle geometry object
If geometry.CoordinatesCount <> 2 Then
	MsgBox("Invalid Fence!")
	Exit Sub
End If

' we need the bounds of the geometry object
rcBounds = geometry.Bounds

Using ie As THBImageEdit = ThbView1.Layers.FirstTHBImageEditObject
	' convert the world units to pixel
	rcBoundsPixel = ie.Cnv.WorldToPixelRc(rcBounds)

	'Create a new image from the cropped part
	Using ieCrop As THBImageEdit = ie.ImageProcessing.CropIntoNewObjectRc(rcBoundsPixel)

	    ' we show the cropped picture in the viewer
	    Using vl As THBViewLayer = ieCrop.InterfaceITHBViewLayer
		vl.Name = "PictureLayer"
		ThbView1.Layers.ClearAndAdd(vl)
	    End Using
	    ThbView1.Zoom.Fit()

	End Using
End Using

After I load the saved vector file in .SHP format the click region event does not work.

Well, when saving 1000 lines wrapped in a THBRegion object the shp file will not store the thb region information, it just stores the geometry data coordinates, id, stylename, rotation,… When loading you will get a layer just containing your lines but not thbregion objects.

After loading your thbvector object from shp copy all objects into THBRegion objects:

vec.BeginUpdate();
THBGeometryList gl = vec.Layer(“LoadedLayer”).All;
THBGeometryList gl2 = gl.Copy();
for(int i=0; i<gl2.Count; i++)
{
	    // create a new thbregion object and populate it with the loaded geometry
	THBRegion region = ...
	    gl2.At(i)
	    // now add it to a new layer
	    vec.Layer(“MyLoadedRegions”).AddGeometry(region);
}
vec.EndUpdate();

From a performance point of view you should call vec.Layer(“MyLoadedRegions”)

just one time and store the THBLayer THBLayer lay = vec.Layer(“MyLoadedRegions”);

Maybe it is much faster to call lay.AddGeometryList instead of 1000 times AddGeometry. So you could fill all thbregion objects into a new geometrylist and add the geometrylist to the layer. But performance will just be interesting with much more geometry objects.

How can I add a custom picture as the placemark?

Each simple pen style has a Pen.Symbol property.
There you can assign a picture.
This works with standard geometry objects.
If you need the Highlight picture too you have to use the more expensive THBRegion wrapper where you can assign the highlight style geomregion.StyleHighlight = styPointSymbolHighlighted

Dim uf As New THBUtilsFactory
Dim imagePin As THBImageStandard
Dim imagePinHigh As THBImageStandard
Dim imgstdfac As New THBImageStandardFactory
imagePin = imgstdfac.CreateTHBImageStandard()
imagePinHigh = imgstdfac.CreateTHBImageStandard()
imagePin.LoadPictureFromFile(Utils.GetPictureDir() + "18.jpg", thbImgFormat.thbifAutoDetect)
imagePinHigh.LoadPictureFromFile(Utils.GetPictureDir() + "22.jpg", thbImgFormat.thbifAutoDetect)
imagePin.KeepAspect = True
imagePin.StretchPic = thbStretch.thbStretchBoth
imagePinHigh.KeepAspect = True
imagePinHigh.StretchPic = thbStretch.thbStretchBoth
styPointSymbol_ = vf.CreateTHBGeometryStyle1("PointSymbol", _
vf.CreateTHBPenGeometryStyle(thbPenStyle.thbPS_SOLID, 30, Utils.RGB(128, 0, 0), 0), vf.CreateTHBBrushGeometryStyle1(thbFillStyle.thbFS_CROSS, Utils.RGB(80, 0, 0), thbGradientMode.thbgmForwardDiagonal, 0))
styPointSymbol_.BackgroundColor = Utils.RGB(255, 255, 255)
styPointSymbol_.Pen.Symbol = imagePin
styPointSymbolHighlighted_ = vf.CreateTHBGeometryStyle1("PointSymbolHighlight", _
vf.CreateTHBPenGeometryStyle(thbPenStyle.thbPS_SOLID, 30, Utils.RGB(128, 0, 0), 0), vf.CreateTHBBrushGeometryStyle1(thbFillStyle.thbFS_CROSS, Utils.RGB(80, 0, 0), thbGradientMode.thbgmForwardDiagonal, 0))
styPointSymbolHighlighted_.BackgroundColor = Utils.RGB(255, 255, 255)
styPointSymbolHighlighted_.Pen.Symbol = imagePinHigh

Dim geomregion As THBRegion
geometry.Style = styPointSymbol
geomregion = vf.CreateTHBRegionGeometry1(geometry, thbView1.Styles.HighlightStyle)
geomregion.StyleHighlight = styPointSymbolHighlighted_

Which license do I need if I want to do vector annotation on raster/vector images manipulating and viewing it in my application. Do I need only THBVector?

To view raster images you need THBImage Standard. It contains the THBView viewer control which is the central viewer component.

For advanced raster image file format support, image processing functions or writing out new raster image files you need the THBImage Pro version.

You can use THBVector to read vector data like DXF. You can then access all layers and geometry objects of the loaded vector data.

To view vector data you need THBImage Standard which contains the THBView viewer control. You can then plug one or more raster or vector layers into the viewer control for viewing.

If you want to add new geometry objects and write out new files you need the THBVector Pro Edition.

So in your case you need THBImage Standard for viewing plus THBVector Standard for vector viewing.

The application handles HPGL like files to drive laser mills. In each files you can find up to 3-4 million of simple 3D vectors. All vectors are grouped at Z layers with a Z distance of 0.005 mm each other, tipically 1000 layers per file. Can your THB Vector SDK show a useful graphic preview of an HPGL file is suitable for a 2D display of a so large amount of data?

THBVector SDK can handle large amount of data and can display it in 2d.

THBVector SDK can not read HPGL, so it’s your job to parse the coordinates. If you read the 2d coordinates you can create lines and add them to THBVector SDK

After adding the line geometry you have the choice to let the user select lines using the Highlight and Selection functionality, or disable this user interaction.

The THBVector SDK interface is identical between ActiveX and .Net, so after writing a Vb 6.0 version you could copy the code to Vb.Net and it will work with a few modifications.

Layers: THB Vector SDK is based on layers. You have a THBView viewer which displays layers. In your case you could plug 1000 THBVector layers into the viewer. Viewing 1000 layers at once sounds not very useful. You have the choice to hide each layer individually. So you could for example turn one layer on and hide all 999 other layers.

To make things more complicated you have two options to handle layers. You can either create 1000 separate THBVector objects and plug them into the THBView viewer. Or you just add a single THBVector object containing 1000 THBLayer layers.

    Dim layer1 As THBLayer = vec.GetLayer("Layer1")
    Dim layer2 As THBLayer = vec.GetLayer("Layer2")
     ...

To better understand the difference, this is like adding 1000 separate files or adding one file which contains 1000 sublayers.

In your case it will be the better choice to just add a single THBVector object containing 1000 sublayers.

        Dim viewlay As THBViewLayer
        Dim vec as THBVector
        vec = New THBVector
        viewlay = vec.InterfaceITHBViewLayer
        viewlay.Name = "HpglFiles"
        thbView1.Layers.ClearAndAdd(viewlay)

' Start adding new vector objects:
vec.BeginUpdate()
' Fill layer 1
    Dim layer As THBLayer = vec.GetLayer("Layer1")
' Add your lines
    Dim coords As THBCoords3D = uf.CreateTHBCoords3D1(coord)
    nextId = nextId  + 1
    layer.AddGeometry(vf.CreateTHBLineGeometry3(coords, 0, styleLine, nextId, ""))
' Finish adding new vector objects:
vec.EndUpdate()

How can I disable the toolbar on the viewer?

Use the THBView.UserInterface functions THBView.UserInterface.Clear THBView.UserInterface.PageNavigation THBView.UserInterface.ProgressBar … ‘maybe you have to call Recreate to make changes immediately visible THBView.UserInterface.Recreate

Please refer to the docu for a complete list of UserInterface functions.

Can I find out if the user is panning? I try to automatically switch to another picture when the user pans to the left border.

Here are some options to solve this

-) Place a vector object that you create using THBVectorFactory (Rectangle) on the picture. In your case on the left side of the picture.
When the user moves the mouse over the object you will get the following THBView event
HighlightChanged: the highlighted objects collection was changed

-) You could use the MouseMove event to watch the current mouse position.
Within the MouseMove event you could access

THBView.Zoom.Factor
THBView.Zoom.Scale

-) Maybe you could use the THBView.MouseWheel event to go to the next picture.

-) These THBView events may help you too Scroll: the user scrolled the view ScrollposChanged: there is a new scrollposition SelectionChanged: the selected objects collection was changed ZoomFactorChanged: the zoomfactor has changed

-) You could place a region geometry object on top of the picture. The user can click on it to get to the next picture.

-) You could place a button next to the thbview control. The user can click on it to get to the next picture.

Which DLLs do I need for deployment?

Please go to the THBImage/bin64/All folder and run the YourSetup.cmd

This folder contains all binaries to run THBImage. The YourSetup.cmd will drop dlls that are not required for your setup depending on your input. This folder contains the Microsoft.VC90.CRT files too.
In case of 32bit pleased do the same in the THBImage/bin32/All folder

After adding a text into the image or JPG file, how can I know that the user is clicking on the text?

Standard geometry objects are part of the selection, at least if selection is enabled (THBView.Selected.Enabled) Clicking on a text would add it to the selection, firing a THBView.SelectionChanged event.

You can use this event to get the selected objects THBView.SelectedLayer.All => you get the clicked text.

To get click events for specific geometry objects you have to wrap the geometry object into a more expensive THBRegion object. After doing this, clicking on the text fires RegionClick event.

Private Sub AddOneStateLabel(ByVal layer As THBLayer, ByVal text As String, ByVal coord As String)
    Dim coords As THBCoords3D = uf.CreateTHBCoords3D1(coord)
    Dim geom As THBGeometry = vf.CreateTHBTextGeometry3(coords, text, thbPosition.thbPosCC, 0, styLabel, regionNextId, "")
    Dim rg As THB.THBRegion = vf.CreateTHBRegionGeometry1(geom, styHighlightLabel)
    regionNextId = regionNextId + 1
    rg.StringData = text
    layer.AddGeometry(rg.InterfaceITHBGeometry)
End Sub

Private Sub thbView1_EventRegionClick(ByVal region As THB.THBRegion) Handles thbView1.EventRegionClick
    If region Is Nothing Then
        Return
    End If

    If Not (region.StringData = "") Then
        MessageBox.Show(region.StringData + " clicked!")
    Else
        If region.Geometry.GeometryType = thbGeometryType.thbGTText Then
            If Not (region.Geometry.Text = "") Then
                MessageBox.Show(region.Geometry.Text + " clicked!")
            End If
        End If
    End If
End Sub

Is your software Royalty free, or do yo have distribution license fees?

Buying a license grants you the right to use the product in your design environment and you have royalty-free distribution rights for executables that use the product as a runtime component.

You are allowed to use a single user license for one 1 developer working with the product. If you are a single developer working on the project then buy a single user license. There are no other hidden fees or royalties.

The pricing is based on developers working on the project. All developers working on a project which includes the product, even though not working directly with the product, are required to purchase a license for product.

The thbimg.zip package contains all files to run THBImage and THBVector.

It contains binaries plus demo projects to evaluate THBImage and THBVector. http://www.thbcomponents.com/dl_thbimg/thbimg.zip

When running the demo project you will see the THBVector buttons.

Where can I find the .Net dll for THBVector?

THB.THBImageLib.dll contains all THB objects. Image processing and vector processing. There are no separate 32+64bit .net dlls, this single dll runs on 32 and 64bit systems. THB.FileUtils.dll is just a helper dll for the demo projects. You may use it but it is not a requirement for using THBImage or THBVector.

THBVector is part of THBImage 5.0 The THBVector object can be used standalone or for viewing it can be plugged into the THBView viewer

Is there a modern Delphi XE code and examples ?

THBImage is an ActiveX control. To be more exact, THBImage is a set of controls and com objects and THBView is the activeX control) Delphi is a very good (not to say the best) activeX container, so adding a new activeX control should not be a problem. I’m not sure if DelphiXE even got better here. We will not add DelphiXE examples except someone overwhelms us with money for doing this. The C# or Vb6 demos (frm or cs files) can be opened using a standard editor. The Form_Load, Form_MouseMove, Form_Close events are very similar.

So basically you can copy paste the code to Delphi and adapt it to pascal language. Which means adding begin var sections.

If you have more specific questions you are welcome . I will try to support your delphi related queries even if we don’t have xe.

Can THBImage Standard save the image to hard disk? Or file format?

THBImageStandard is intended for viewing only. You can load basic picture file formats like gif, png, jpg and plug it into THBView for viewing.

Would we able to set which layer to appear/disable during runtimes?

THBViewLayers have properties to set the layer visible. You could also make the visibility scale dependent which means the layer is just visible when you zoom in very close.

Can I add custom control on each layer? Example I have 3 layer on top of 1 image, then can I embedded 1 textbox (win forms) into layer1, 2 text box (win forms) into layer 2 and 3 text box into layer 3, then which I switch on/off which layer, the textbox appear according to the layer display.

This doesn’t work in this way. You can plug a vector annotation layer or multiple vector annotation layers on top of the image. (THBView.Layers.Add) The vector annotation layer can display bitmap symbols, circles, lines, shapes, text that has a tooltip and is clickable. When clicking on the object you could open your win form. You can not edit directly in the viewer.

Can I save each layer into different file format?

Well you plug THBImageStandard, THBImageEdit, THBVector objects into the THBView object for viewing.

So you can whenever you want access, change or save each layer separately.

THBImageEdit.SavePicture…

THBVector.Save…

Can I save all layers together with the image that sit at bottom of layer into a single bitmap file?

You can create a kind of screenshot which writes all layers independent of its type (vector or raster image) into a single picture.

You will get a new THBImageEdit object which you can then save to disk using THBImageEdit.SavePicture

// Returns the size in pixels necessary to draw 
// to a THBImageEdit object using the current WorldUnitsPerPixel
// values. Use this property to precalculate the output size
// and take the steps necessary to prevent huge output sizes.
CSize GetDrawToTHBImageEditSizeInPixels(
	   const CRectd& rcWorld // worldarea to draw
	   )

// Draw to a THBImageEdit object. Draws the specified worldarea
void DrawToTHBImageEdit(
   ITHBImageEditSp* ie,    // we draw to this object, it should be a new empty object
   int nWidth, int nHeight, // destination output size in pixels
   BOOL bHasRcSrcWorld, const CRectd& rcSrcWorld, // you can render a specific area of the world too
   BOOL bAllowCachedDrawing     // => allow cached drawing content)
   )

Saving pictures using THBImageEdit.SavePicture… requires THBImage Pro.
Using clickable vector annotation requires THBVector Standard.
Saving the annotation into one of the supported vector files (dxf,shape) requires thbvector pro, you could save and load vector objects on your own too.

When I add lines to the vector layer, I find that their origin seems to be in the bottom left rather than the top left (i.e., if I draw from (0,0) to the center, the line appears from the lower left to the center). Is there a way I can change the coordinate system on the vector layer to have its coordinate origin in the top left?

Vector coordinates don’t use the pixel coordinate system approach where 0,0 is top left, instead we use world coordinates which have the origin 0,0 at bottom left.

There is no flag to change the coordinate system.
Each THBViewLayer has assigned a coordinate area.
A THBImageEdit layer which contains a 800x600 picture will use a left top right bottom world rect with these coordinates: 0.0 600.0 800.0 0.0

To convert from world to pixel and back again you can use

THBImageEdit.Cnv.WorldToPixelRc
THBImageEdit.Cnv.PixelToWorldRc

So if you get a world rectangle geometry object use

THBRect rcPixel = THBImageEdit.Cnv.WorldToPixelRc(Geometry.Bounds);

How to locate a particular region within a layer. We used to use THBImage.Regions.GetByID extensively to retrieve regions by a numeric ID, but I can’t find an analog to that in 5.0. Is there one? If I assign an ID at creation time (it appears to be available in the constructor), how can I then search for that region by the assigned ID?

There is no way to lookup by region (or now geometry) id.

-) When clicking on geometry objects THBView will fire an event to notify you about the click action. In this case you don’t need a lookup because the event passes the clicked geometry along with the event.

-) To implement the Lookup by Id, I suggest you to use your own Dictionary

Dictionary<int, THB.THBGeometry> lookup = new Dictionary<int, THB.THBGeometry>();

When adding geometry, add it to the dictionary too. When searching the geometry by Id use your Dictionary. The Dictionary returns the THBGeometry object. To zoom to the geometry use

THBView.Zoom.ToWorldRectangle(lookup[Id].Bounds);

Normally you create THB.THBGeometry objects, add them to the layer and then Dispose them.

vec_.BeginUpdate();
layBounds_.RemoveAll();
using (THBGeometry g = vf_.CreateTHBRectangleGeometry2(
    uf_.CreateTHBRectd(rc.Left, rc.Top, rc.Right, rc.Bottom),
    geometrystyleinvisible_, 0, "bounds"))
    layBounds_.AddGeometry(g);
vec_.EndUpdate();

In your case you must not Dispose the object because you still use it within the lookup Dictionary. You may Dispose all THB.THBGeometry objects stored in the dictionary when clearing the layers or closing the form.

foreach(THB.THBGeometry geom in lookup.Values)
    geom.Dispose();
lookup.Clear();

-) The brute force solution is to use

using(THBGeometryList gl = THBLayer.GetAll())
{
	for(int i=0; i&lt;gl.Count; i++)
	using(THBGeometry geom = gl.At(i))
	    if(geom.Id == searchid)
	    {
			do something;
			break;
	    }
}

Here we first return all geometry objects as a THBGeometryList.
Then we iterate over all geometry objects searching for the Id.
If you have really many geometry objects this may be a performance bottleneck.

After the THBView.Commands.Start(thbCommand.thbCmdRect) you are able to draw the rectangle. Unfortunally, the rectangle is being drawn with a non-transparant BLUE color, so you can no longer view the rectangular area underneath you’re selecting.

When using nice transparency effects gdi+ offers better support here.
The gdi drawing provider is faster and can use pen styles like dashed, dotted which you could use instead of transparencies.

So your first choice is the drawing provider:

THBView1.Options.DrawingProvider = thbdpGDIPlus

The style for commands is the one you need

THBView1.Styles.CommandsStyle

Color values are defined by 3 color parts (red, green, blue) and an optional alpha value Use the RGBA function to apply colors along with the transparency.

// ------------------------------------------------
// returns an RGBA color value
public static int RGBA(int r, int g, int b, int a)
{
    return (a << 24) + (b << 16) + (g << 8) + r;
}

Create your pen or brush using the RGBA function

vf.CreateTHBPenGeometryStyle(thbPS_SOLID, 2, RGBA(255, 204, 51, 128), 0)

A value of 255 means opaque and 128 means semi transparent 0 means completely transparent.

' Outfit when digitizing new geometry objects
THBView1.Styles.CommandsStyle = vf.CreateTHBGeometryStyle("Command", _
vf.CreateTHBPenGeometryStyle(thbPS_SOLID, 2, THBColor(255, 204, 51), 0), _
vf.CreateTHBBrushGeometryStyle1(thbFS_CROSS, THBColor(255, 204, 51), thbgmBackwardDiagonal, 0), _
vf.CreateTHBFontGeometryStyle1(10, "Arial"))
THBView1.Styles.CommandsStyle.BackgroundColor = THBColor(255, 255, 255)

' style of snapping elements
THBView1.Styles.SnapStyle = vf.CreateTHBGeometryStyle("Snap", _
vf.CreateTHBPenGeometryStyle(thbPS_SOLID, 1, THBColor(255, 51, 0), 0), _
vf.CreateTHBBrushGeometryStyle1(thbFS_CROSS, THBColor(255, 51, 0), thbgmBackwardDiagonal, 0), _
vf.CreateTHBFontGeometryStyle1(10, "Arial"))
THBView1.Styles.SnapStyle.BackgroundColor = THBColor(255, 255, 255)
THBView1.Styles.SnapStyle.Opacity = 40

' selected objects are drawn this way
THBView1.Styles.SelectionStyle = vf.CreateTHBGeometryStyle("Selection", _
vf.CreateTHBPenGeometryStyle(thbPS_SOLID, 2, THBColor(255, 179, 0), 0), _
vf.CreateTHBBrushGeometryStyle1(thbFS_CROSS, THBColor(255, 179, 0), thbgmBackwardDiagonal, 0), _
vf.CreateTHBFontGeometryStyle1(10, "Arial"))

THBView1.Styles.SelectionStyle.BackgroundColor = THBColor(255, 255, 255)
THBView1.Styles.SelectionStyle.Opacity = 40

' highlighted objects are drawn this way
THBView1.Styles.HighlightStyle = vf.CreateTHBGeometryStyle("Highlight", _
vf.CreateTHBPenGeometryStyle(thbPS_SOLID, 10, THBColor(204, 255, 0), 0), _
vf.CreateTHBBrushGeometryStyle1(thbFS_CROSS, THBColor(204, 255, 0), thbgmBackwardDiagonal, 0), _
vf.CreateTHBFontGeometryStyle1(10, "Arial"))
THBView1.Styles.HighlightStyle.BackgroundColor = THBColor(255, 255, 255)
THBView1.Styles.HighlightStyle.Opacity = 40

How to access Selected/Highlighted Geometry Objects? I need to look at the properties of the selected/highlighted geometry objects in a vector layer.

Use

THBView.Highlighted
THBView.HighlightedLayer
THBView.Selected
THBView.SelectedLayer

to access selected or highlighted objects.

The selected layer THBView.SelectedLayer is a standard THBLayer and contains all selected geometry objects. Use THBView.SelectedLayer.All to return a list of all selected geometry objects.

When an image is loaded into the image control and the user right clicks, and selects zoom, is it possible to set the zoom factor so that it doesn’t zoom in by so much each time?

You can use

THBView.Zoom.ZoomPlus
THBView.Zoom.ZoomMinus
THBView.Zoom.Factor

to zoom on your own.
You may need to call THBView.Redraw to update the display after zooming.

To replace our default zoom + - buttons and to add your own buttons use

THBView.UserInterface.AddCustomButton
THBView.UserInterface.Recreate

AddCustomButton adds a user interface button to the viewer

Use THBView ExecuteAction event along with the actionid passed in AddCustomButton to implement your own action. ExecuteAction: Notification that an action was executed, either through popupmenu, userinterface or animation action

I have geometry data in the ‘spreadsheet’ which are points, lines, circles etc., can THBVector visualise this? If the user changes the data, the visualisation should be updated.

Create a new THBVector object.
Create a new layer

THBVector vec = new THBVector();

// Call BeginUpdate and EndUpdate on the THBVector object
vec.BeginUpdate();
THBLayer lay = vec.Layer("YourLayer");

lay.AddGeometry ...

vec.EndUpdate();

When finished plug the THBVector object into THBView for viewing.

Call THBView.Zoom.Fit to fit to the new geometry.

When updating your geometry

// Call BeginUpdate and EndUpdate on the THBVector object
vec.BeginUpdate();

// Clear layer
lay.RemoveAll();

// reconstruct your geometry
lay.AddGeometry ...

vec.EndUpdate();

To create geometry use the supplied factory functions.

THBVectorFactory vecfac = new THBVectorFactory();
vecfac.CreateTHBPolygonGeometry...

There are different versions where you can pass your coordinate points. This should get you started.

How Can I make the image fit to height or fit to width?

Use THBView.Zoom.FitHorizontal to fit to width and FitVertical to fit to height

FitHorizontal: Horizontally fit the content to available screen space
FitVertical: Vertically fit the content to available screen space