←Select platform

HitTestZone Method

Summary
Gets the zero-based index of the zone under a certain point.
Syntax
C#
VB
Objective-C
C++
Java
public int HitTestZone( 
   LeadPoint point 
) 
Function HitTestZone( _ 
   ByVal point As LeadPoint _ 
) As Integer 
- (NSUInteger)hitTestZone:(LeadPoint)point 
public int hitTestZone(LeadPoint point) 
int HitTestZone(  
   LeadPoint point 
)  

Parameters

point
The test point in pixels.

Return Value

The zero-based index of the zone under point, if no zone is under the test point, this method will return -1.

Remarks

You can use this method to check whether a zone (either added manually or automatically) is under a given test point. For example, if you have a Windows Forms based application with the current IOcrPage in an ImageViewer control. You might want to draw the zones on the surface of the viewer. For this, you can use the GetZoneBoundsInPixels methods. If you want to allow the user to click with the mouse on the viewer to select and de-select zones, you can use HitTestZone.

Example

This example will view the OCR Page and its zones in an ImageViewer control. It will then allow the user to select/deselect zones with the mouse.

C#
VB
using Leadtools; 
using Leadtools.Codecs; 
using Leadtools.Ocr; 
using Leadtools.Forms.Common; 
using Leadtools.Document.Writer; 
using Leadtools.WinForms; 
using Leadtools.Drawing; 
using Leadtools.ImageProcessing; 
using Leadtools.ImageProcessing.Color; 
 
// Assume Form1 is a Windows.Forms form in your application 
 
// The OCR engine we are using 
private IOcrEngine _ocrEngine; 
// The OCR page we are using 
private IOcrPage _ocrPage; 
 
// Our raster image viewer instance 
private RasterImageViewer _viewer; 
 
public Form1() 
{ 
   InitializeComponent(); 
 
   // Initialize the raster image viewer 
   // Turn on use DPI, center the image, add border padding and frame shadow to show that our calculations will be 
   // independent on all of those extra options 
   _viewer = new RasterImageViewer(); 
   _viewer.Dock = DockStyle.Fill; 
   _viewer.BackColor = SystemColors.AppWorkspace; 
   _viewer.UseDpi = true; 
   _viewer.BorderPadding.All = 8; 
   _viewer.FrameSize = new SizeF(1, 1); 
   _viewer.FrameShadowSize = new SizeF(2, 2); 
   _viewer.SizeMode = RasterPaintSizeMode.Normal; 
   _viewer.HorizontalAlignMode = RasterPaintAlignMode.Center; 
   _viewer.VerticalAlignMode = RasterPaintAlignMode.Center; 
   _viewer.AutoDisposeImages = true; 
   _viewer.InteractiveMode = RasterViewerInteractiveMode.None; 
 
   // Turn on scale to gray painting in the viewer 
   RasterPaintProperties props = _viewer.PaintProperties; 
   props.PaintDisplayMode |= RasterPaintDisplayModeFlags.ScaleToGray; 
   _viewer.PaintProperties = props; 
 
   // Subscribe to the viewer events we need 
   _viewer.KeyDown += new KeyEventHandler(_viewer_KeyDown); 
   _viewer.MouseDown += new MouseEventHandler(_viewer_MouseDown); 
   _viewer.PostImagePaint += new PaintEventHandler(_viewer_PostImagePaint); 
 
   Controls.Add(_viewer); 
   _viewer.BringToFront(); 
 
   // Create and startup the OCR engine 
   _ocrEngine = OcrEngineManager.CreateEngine(OcrEngineType.LEAD); 
   _ocrEngine.Startup(null, null, null, LEAD_VARS.OcrLEADRuntimeDir); 
 
   // Load an image into the OCR document 
   string tifFileName = Path.Combine(LEAD_VARS.ImagesDir, "Ocr1.tif"); 
   _ocrPage = _ocrEngine.CreatePage(_ocrEngine.RasterCodecsInstance.Load(tifFileName, 1), OcrImageSharingMode.AutoDispose); 
 
   // Do auto zone 
   _ocrPage.AutoZone(null); 
 
   // AutoZone does not specify a name for the zones, so loop through all the zones and set their names 
   // to a unique value. We will use the name in the paint code later 
   IOcrZoneCollection ocrZones = _ocrPage.Zones; 
   for (int i = 0; i < ocrZones.Count; i++) 
   { 
      OcrZone ocrZone = ocrZones[i]; 
 
      // Construct the name from the ID 
      ocrZone.Name = string.Format("Zone {0}", ocrZone.Id); 
 
      ocrZones[i] = ocrZone; 
   } 
 
   // Show the same image in the viewer 
   _viewer.Image = _ocrPage.GetRasterImage(); 
 
   // Note, the image we got from GetRasterImage is a copy of the image in the engine 
   // Since we set the AutoDisposeImages of the viewer to "true", the image will be disposed 
   // when the viewer is disposed at application termination 
 
   Text = "+ to zoom in, - to zoom out, enter to return to 100%. Select the zones with the mouse"; 
} 
 
protected override void OnFormClosed(FormClosedEventArgs e) 
{ 
   // Dispose the page 
   _ocrPage.Dispose(); 
 
   // Shutdown the OCR engine 
   _ocrEngine.Dispose(); 
 
   base.OnFormClosed(e); 
} 
 
private void _viewer_KeyDown(object sender, KeyEventArgs e) 
{ 
   const double zoomRatio = 1.2; 
   double scaleFactor = _viewer.ScaleFactor; 
 
   switch (e.KeyCode) 
   { 
      case Keys.Add: 
      case Keys.Oemplus: 
         // Zoom in 
         scaleFactor *= zoomRatio; 
         e.Handled = true; 
         break; 
 
      case Keys.Subtract: 
      case Keys.OemMinus: 
         // Zone out 
         scaleFactor /= zoomRatio; 
         e.Handled = true; 
         break; 
 
      case Keys.Enter: 
         scaleFactor = 1; 
         e.Handled = true; 
         break; 
   } 
 
   const double minimumScaleFactor = 0.05; 
   const double maximumScaleFactor = 11; 
 
   scaleFactor = Math.Max(minimumScaleFactor, Math.Min(maximumScaleFactor, scaleFactor)); 
 
   // Check if scale factor has changed 
   if (scaleFactor != _viewer.ScaleFactor) 
   { 
      _viewer.BeginUpdate(); 
 
      // Yes, zoom keeping the center of the image 
 
      // Get what you see in physical coordinates 
      Rectangle rc = Rectangle.Intersect(_viewer.PhysicalViewRectangle, _viewer.ClientRectangle); 
      // Get the center of what you see in physical coordinates 
      PointF center = new PointF(rc.Left + rc.Width / 2, rc.Top + rc.Height / 2); 
      Transformer t = new Transformer(_viewer.Transform); 
      // Get the center of what you see in logical coordinates 
      center = t.PointToLogical(center); 
 
      _viewer.ScaleFactor = scaleFactor; 
 
      // Bring the original center into the view center 
      t = new Transformer(_viewer.Transform); 
      // Get the center of what you saw before the zoom in physical coordinates 
      center = t.PointToPhysical(center); 
      // Bring the old center into the center of the view 
      _viewer.CenterAtPoint(Point.Round(center)); 
 
      _viewer.EndUpdate(); 
   } 
} 
 
private void _viewer_MouseDown(object sender, MouseEventArgs e) 
{ 
   // Perform hit-testing on the zones 
   if (_ocrEngine != null && _ocrEngine.IsStarted && _ocrPage != null && e.Button == MouseButtons.Left) 
   { 
      // Get the transform of the viewer 
      // Use the transform that takes the DPI into consideration since we turned that on 
      using (Matrix matrix = _viewer.GetTransformWithDpi()) 
      { 
         Transformer t = new Transformer(matrix); 
 
         // Convert the mouse click coordinates from physical (viewer) to logical (image) 
         PointF point = new PointF(e.X, e.Y); 
         point = t.PointToLogical(point); 
 
         // Hit test the zones 
         // An alternative to calling HitTestZone is to loop through all the zones 
         // and get the value of .Bounds in pixels, then check if the point is inside 
         // the boundaries. 
         LeadPoint lPoint = new LeadPoint((int)point.X, (int)point.Y); 
         int zoneIndex = _ocrPage.HitTestZone(lPoint); 
         if (zoneIndex != -1) 
         { 
            // We hit a zone, loop through all the zones, unselect all but the hit tested zone 
            for (int index = 0; index < _ocrPage.Zones.Count; index++) 
            { 
               // Since OcrZone is a structure, we cannot simply do 
               // ocrZone.Zones[index].Name = value 
               // We have to get a copy of the structure, modify it and set it back 
 
               OcrZone ocrZone = _ocrPage.Zones[index]; 
 
               if (index != zoneIndex) 
                  ocrZone.Name = null; 
               else 
                  ocrZone.Name = "Selected"; 
 
               _ocrPage.Zones[index] = ocrZone; 
            } 
 
            // Re-paint the viewer to show the new zones 
            _viewer.Invalidate(); 
         } 
      } 
   } 
} 
 
private void _viewer_PostImagePaint(object sender, PaintEventArgs e) 
{ 
   // Draw the zones on the viewer in their correct location 
   if (_ocrEngine != null && _ocrEngine.IsStarted && _ocrPage != null) 
   { 
      // Get the transform of the viewer 
      // Use the transform that takes the DPI into consideration since we turned that on 
      using (Matrix matrix = _viewer.GetTransformWithDpi()) 
      { 
         Transformer t = new Transformer(matrix); 
 
         Pen normalPen = new Pen(Color.Blue, 1); 
         Pen selectedPen = new Pen(Color.Red, 2); 
         selectedPen.DashStyle = DashStyle.Dash; 
 
         foreach (OcrZone ocrZone in _ocrPage.Zones) 
         { 
            // Get the zone bounds in pixels 
            // You can also use _ocrPage.GetZoneBoundsInPixels here 
            RectangleF zoneBounds = new RectangleF(ocrZone.Bounds.Left, ocrZone.Bounds.Top, ocrZone.Bounds.Width, ocrZone.Bounds.Height); 
 
            // This rectangle is in image (logical) coordinates with top-left view perspective 
            // Convert to the physical coordinates of the viewer 
            zoneBounds = t.RectangleToPhysical(zoneBounds); 
 
            // Now draw this zone on the viewer surface 
            if (ocrZone.Name == "Selected") 
               e.Graphics.DrawRectangle(selectedPen, zoneBounds.X, zoneBounds.Y, zoneBounds.Width - 1, zoneBounds.Height - 1); 
            else 
               e.Graphics.DrawRectangle(normalPen, zoneBounds.X, zoneBounds.Y, zoneBounds.Width - 1, zoneBounds.Height - 1); 
 
            // Draw the zone name on the left hand corner of the zone 
            // Note, in a real application you might want to have an option to show/hide the zone names (labels) 
            SizeF labelSize = e.Graphics.MeasureString(ocrZone.Name, Font); 
            RectangleF labelRectangle = new RectangleF(zoneBounds.X, zoneBounds.Y - labelSize.Height, labelSize.Width, labelSize.Height); 
            e.Graphics.FillRectangle(Brushes.Yellow, labelRectangle); 
            e.Graphics.DrawString(ocrZone.Name, Font, Brushes.Black, labelRectangle.X, labelRectangle.Y); 
         } 
      } 
   } 
} 
 
static class LEAD_VARS 
{ 
   public const string ImagesDir = @"C:\LEADTOOLS21\Resources\Images"; 
   public const string OcrLEADRuntimeDir = @"C:\LEADTOOLS21\Bin\Common\OcrLEADRuntime"; 
} 
Imports Leadtools 
Imports Leadtools.Codecs 
Imports Leadtools.Ocr 
Imports Leadtools.Forms 
Imports Leadtools.Document.Writer 
Imports Leadtools.WinForms 
Imports Leadtools.Drawing 
Imports Leadtools.ImageProcessing 
Imports Leadtools.ImageProcessing.Color 
 
' Assume Form1 is a Windows.Forms form in your application 
 
' The OCR engine we are using 
Private _ocrEngine As IOcrEngine 
' The OCR page we are using 
Private _ocrPage As IOcrPage 
 
' Our raster image viewer instance 
Private _viewer As RasterImageViewer 
 
Public Sub New() 
   InitializeComponent() 
 
   ' Initialize the raster image viewer 
   ' Turn on use DPI, center the image, add border padding and frame shadow to show that our calculations will be 
   ' independent on all of those extra options 
   _viewer = New RasterImageViewer() 
   _viewer.Dock = DockStyle.Fill 
   _viewer.BackColor = SystemColors.AppWorkspace 
   _viewer.UseDpi = True 
   _viewer.BorderPadding.All = 8 
   _viewer.FrameSize = New SizeF(1, 1) 
   _viewer.FrameShadowSize = New SizeF(2, 2) 
   _viewer.SizeMode = RasterPaintSizeMode.Normal 
   _viewer.HorizontalAlignMode = RasterPaintAlignMode.Center 
   _viewer.VerticalAlignMode = RasterPaintAlignMode.Center 
   _viewer.AutoDisposeImages = True 
   _viewer.InteractiveMode = RasterViewerInteractiveMode.None 
 
   ' Turn on scale to gray painting in the viewer 
   Dim props As RasterPaintProperties = _viewer.PaintProperties 
   props.PaintDisplayMode = props.PaintDisplayMode Or RasterPaintDisplayModeFlags.ScaleToGray 
   _viewer.PaintProperties = props 
 
   ' Subscribe to the viewer events we need 
   AddHandler _viewer.KeyDown, AddressOf _viewer_KeyDown 
   AddHandler _viewer.MouseDown, AddressOf _viewer_MouseDown 
   AddHandler _viewer.PostImagePaint, AddressOf _viewer_PostImagePaint 
 
   Controls.Add(_viewer) 
   _viewer.BringToFront() 
 
   ' Create and startup the OCR engine 
   _ocrEngine = OcrEngineManager.CreateEngine(OcrEngineType.LEAD) 
   _ocrEngine.Startup(Nothing, Nothing, Nothing, LEAD_VARS.OcrLEADRuntimeDir) 
 
   ' Load an image into the OCR document 
   Dim tifFileName As String = Path.Combine(LEAD_VARS.ImagesDir, "Ocr1.tif") 
   _ocrPage = _ocrEngine.CreatePage(_ocrEngine.RasterCodecsInstance.Load(tifFileName, 1), OcrImageSharingMode.AutoDispose) 
 
   ' Do auto zone 
   _ocrPage.AutoZone(Nothing) 
 
   ' AutoZone does not specify a name for the zones, so loop through all the zones and set their names 
   ' to a unique value. We will use the name in the paint code later 
   Dim ocrZones As IOcrZoneCollection = _ocrPage.Zones 
   For i As Integer = 0 To ocrZones.Count - 1 
      Dim ocrZone As OcrZone = ocrZones(i) 
 
      ' Construct the name from the ID 
      ocrZone.Name = String.Format("Zone {0}", ocrZone.Id) 
 
      ocrZones(i) = ocrZone 
   Next 
 
   ' Show the same image in the viewer 
   _viewer.Image = _ocrPage.GetRasterImage() 
 
   ' Note, the image we got from GetRasterImage is a copy of the image in the engine 
   ' Since we set the AutoDisposeImages of the viewer to "true", the image will be disposed 
   ' when the viewer is disposed at application termination 
 
   Text = "+ to zoom in, - to zoom out, enter to return to 100%. Select the zones with the mouse" 
End Sub 
 
Protected Overrides Sub OnFormClosed(e As FormClosedEventArgs) 
   ' Dispose the page 
   _ocrPage.Dispose() 
 
   ' Shutdown the OCR engine 
   _ocrEngine.Dispose() 
 
   MyBase.OnFormClosed(e) 
End Sub 
 
Private Sub _viewer_KeyDown(sender As Object, e As KeyEventArgs) 
   Const zoomRatio As Double = 1.2 
   Dim scaleFactor As Double = _viewer.ScaleFactor 
 
   Select Case e.KeyCode 
      Case Keys.Add, Keys.Oemplus 
         ' Zoom in 
         scaleFactor *= zoomRatio 
         e.Handled = True 
         Exit Select 
 
      Case Keys.Subtract, Keys.OemMinus 
         ' Zoom out 
         scaleFactor /= zoomRatio 
         e.Handled = True 
         Exit Select 
 
      Case Keys.Enter 
         scaleFactor = 1 
         e.Handled = True 
         Exit Select 
   End Select 
 
   Const minimumScaleFactor As Double = 0.05 
   Const maximumScaleFactor As Double = 11 
 
   scaleFactor = Math.Max(minimumScaleFactor, Math.Min(maximumScaleFactor, scaleFactor)) 
 
   ' Check if scale factor has changed 
   If scaleFactor <> _viewer.ScaleFactor Then 
      _viewer.BeginUpdate() 
 
      ' Yes, zoom keeping the center of the image 
 
      ' Get what you see in physical coordinates 
      Dim rc As Rectangle = Rectangle.Intersect(_viewer.PhysicalViewRectangle, _viewer.ClientRectangle) 
      ' Get the center of what you see in physical coordinates 
      Dim center As New PointF(rc.Left + rc.Width \ 2, rc.Top + rc.Height \ 2) 
      Dim t As New Transformer(_viewer.Transform) 
      ' Get the center of what you see in logical coordinates 
      center = t.PointToLogical(center) 
 
      _viewer.ScaleFactor = scaleFactor 
 
      ' Bring the original center into the view center 
      t = New Transformer(_viewer.Transform) 
      ' Get the center of what you saw before the zoom in physical coordinates 
      center = t.PointToPhysical(center) 
      ' Bring the old center into the center of the view 
      _viewer.CenterAtPoint(Point.Round(center)) 
 
      _viewer.EndUpdate() 
   End If 
End Sub 
 
Private Sub _viewer_MouseDown(sender As Object, e As MouseEventArgs) 
   ' Perform hit-testing on the zones 
   If _ocrEngine IsNot Nothing AndAlso _ocrEngine.IsStarted AndAlso _ocrPage IsNot Nothing AndAlso e.Button = MouseButtons.Left Then 
      ' Get the transform of the viewer 
      ' Use the transform that takes the DPI into consideration since we turned that on 
      Using matrix As Matrix = _viewer.GetTransformWithDpi() 
         Dim t As New Transformer(matrix) 
 
         ' Convert the mouse click coordinates from physical (viewer) to logical (image) 
         Dim point As New PointF(e.X, e.Y) 
         point = t.PointToLogical(point) 
 
         ' Hit test the zones 
         ' An alternative to calling HitTestZone is to loop through all the zones 
         ' and get the value of .Bounds in pixels, then check if the point is inside 
         ' the boundaries. 
         Dim lPoint As New LeadPoint(CInt(Math.Truncate(point.X)), CInt(Math.Truncate(point.Y))) 
         Dim zoneIndex As Integer = _ocrPage.HitTestZone(lPoint) 
         If zoneIndex <> -1 Then 
            ' We hit a zone, loop through all the zones, unselect all but the hit tested zone 
            For index As Integer = 0 To _ocrPage.Zones.Count - 1 
               ' Since OcrZone is a structure, we cannot simply do 
               ' ocrZone.Zones[index].Name = value 
               ' We have to get a copy of the structure, modify it and set it back 
 
               Dim ocrZone As OcrZone = _ocrPage.Zones(index) 
 
               If index <> zoneIndex Then 
                  ocrZone.Name = Nothing 
               Else 
                  ocrZone.Name = "Selected" 
               End If 
 
               _ocrPage.Zones(index) = ocrZone 
            Next 
 
            ' Re-paint the viewer to show the new zones 
            _viewer.Invalidate() 
         End If 
      End Using 
   End If 
End Sub 
 
Private Sub _viewer_PostImagePaint(sender As Object, e As PaintEventArgs) 
   ' Draw the zones on the viewer in their correct location 
   If _ocrEngine IsNot Nothing AndAlso _ocrEngine.IsStarted AndAlso _ocrPage IsNot Nothing Then 
      ' Get the transform of the viewer 
      ' Use the transform that takes the DPI into consideration since we turned that on 
      Using matrix As Matrix = _viewer.GetTransformWithDpi() 
         Dim t As New Transformer(matrix) 
 
         Dim normalPen As New Pen(Color.Blue, 1) 
         Dim selectedPen As New Pen(Color.Red, 2) 
         selectedPen.DashStyle = DashStyle.Dash 
 
         For Each ocrZone As OcrZone In _ocrPage.Zones 
            ' Get the zone bounds in pixels 
            ' You can also use _ocrPage.GetZoneBoundsInPixels here 
            Dim ltzoneBounds As LeadRect = ocrZone.Bounds 
            Dim zoneBounds As New RectangleF(ltzoneBounds.Left, ltzoneBounds.Top, ltzoneBounds.Width, ltzoneBounds.Height) 
 
            ' This rectangle is in image (logical) coordinates with top-left view perspective 
            ' Convert to the physical coordinates of the viewer 
            zoneBounds = t.RectangleToPhysical(zoneBounds) 
 
            ' Now draw this zone on the viewer surface 
            If ocrZone.Name = "Selected" Then 
               e.Graphics.DrawRectangle(selectedPen, zoneBounds.X, zoneBounds.Y, zoneBounds.Width - 1, zoneBounds.Height - 1) 
            Else 
               e.Graphics.DrawRectangle(normalPen, zoneBounds.X, zoneBounds.Y, zoneBounds.Width - 1, zoneBounds.Height - 1) 
            End If 
 
            ' Draw the zone name on the left hand corner of the zone 
            ' Note, in a real application you might want to have an option to show/hide the zone names (labels) 
            Dim labelSize As SizeF = e.Graphics.MeasureString(ocrZone.Name, Font) 
            Dim labelRectangle As New RectangleF(zoneBounds.X, zoneBounds.Y - labelSize.Height, labelSize.Width, labelSize.Height) 
            e.Graphics.FillRectangle(Brushes.Yellow, labelRectangle) 
            e.Graphics.DrawString(ocrZone.Name, Font, Brushes.Black, labelRectangle.X, labelRectangle.Y) 
         Next 
      End Using 
   End If 
End Sub 
 
Public NotInheritable Class LEAD_VARS 
   Public Const ImagesDir As String = "C:\LEADTOOLS21\Resources\Images" 
   Public Const OcrLEADRuntimeDir As String = "C:\LEADTOOLS21\Bin\Common\OcrLEADRuntime" 
End Class 
Requirements

Target Platforms

Help Version 21.0.2021.7.2
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.

Leadtools.Ocr Assembly
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.