PDF Select all search results

Questions, comments and suggestions concerning VintaSoft PDF .NET Plug-in.

Moderator: Alex

Post Reply
maggarwal
Posts: 11
Joined: Tue Jan 29, 2013 1:34 am

PDF Select all search results

Post by maggarwal »

Hi,

How can I highlight all the search results in a document? I know I can cycle through the search results but I couldn't find any way to highlight all the matches in the document.

Thanks
Alex
Site Admin
Posts: 2304
Joined: Thu Jul 10, 2008 2:21 pm

Re: PDF Select all search results

Post by Alex »

Hello,

You need do the following steps if you want to highlight some objects on the image:
  • Create class, for example, HighlightedSearchResult, that represents the highlighted search result. This class must implement the IBoundedObject interface.
  • Create an instance of the HighlightTool class and make this instance as active visual tool in the image viewer.
  • Create instance of the HighlightedSearchResult class for each search result and add it to the collection of highlighted objects - HighlightTool.Items.
It's all that you need to do.

Best regards, Alexander
maggarwal
Posts: 11
Joined: Tue Jan 29, 2013 1:34 am

Re: PDF Select all search results

Post by maggarwal »

How can I get all the search results? I can find text but that only runs once. Find next goes infinitely and causes stack overflow exception. Please advise. Thanks

Code: Select all

        private void PDFViewerToolOnTextSearched(object sender, PdfTextSearchedEventArgs e)
        {
            if (e.FoundTextRegion == null)
            {
                ImageViewer.VisualTool = _highlightTool;
                _highlightTool.SelectedItem = _highlightTool.Items.First().Objects.FirstOrDefault();
            }
            else
            {
                var highlight =
                    new HighlightedSearchResult(new Rectangle((int) e.FoundTextRegion.Rectangle.X,
                                                              (int) e.FoundTextRegion.Rectangle.Y,
                                                              (int) e.FoundTextRegion.Rectangle.Width,
                                                              (int) e.FoundTextRegion.Rectangle.Height));
                _highlightTool.Items.Add(new ColoredObjects<HighlightedSearchResult>(new[] {highlight}));
                _pdfViewerTool.FindTextNext(e.SearchingText, PdfViewerTool.FindTextMode.CurrentPage, new FindTextOptions());
            }
        }
Alex
Site Admin
Posts: 2304
Joined: Thu Jul 10, 2008 2:21 pm

Re: PDF Select all search results

Post by Alex »

Hello,

Your code is not correct.

First, you need create class that will represent the highlighted search result. Here is a code of such class:

Code: Select all

class HightlightRectangle: IBoundedObject
{
    Rectangle _rect;

    public HightlightRectangle(Rectangle rect)
    {
        _rect = rect;
    }

    public Rectangle GetBoundingBox()
    {
        return _rect; 
    }
}
Next, you need create visual tool which will show highlighted objects:

Code: Select all

class TextRegionHighlightTool : HighlightTool<HightlightRectangle>
{
    Dictionary<VintasoftImage, TextRegion[]> _imageToRegions;

    public TextRegionHighlightTool(Dictionary<VintasoftImage, TextRegion[]> imageToRegions)
    {
        _imageToRegions = imageToRegions;
    }

    protected override void OnActivate(EventArgs e)
    {
        base.OnActivate(e);
        ImageViewer.FocusedIndexChanged += new EventHandler<FocusedIndexChangedEventArgs>(ImageViewer_FocusedIndexChanged);
        ImageViewer.RenderingSettingsChanged += new EventHandler(ImageViewer_RenderingSettingsChanged);
        UpdateItems();
    }

    protected override void OnDeactivate(EventArgs e)
    {
        ImageViewer.FocusedIndexChanged -= new EventHandler<FocusedIndexChangedEventArgs>(ImageViewer_FocusedIndexChanged);
        ImageViewer.RenderingSettingsChanged -= new EventHandler(ImageViewer_RenderingSettingsChanged);
        base.OnDeactivate(e);
    }

    private void UpdateItems()
    {
        VintasoftImage image = ImageViewer.Image;
        TextRegion[] regions = _imageToRegions[image];
        HightlightRectangle[] hightlightTextRegions = new HightlightRectangle[regions.Length];
        PdfPage page = PdfViewerTool.GetPageFromImage(ImageViewer.Image);
        for (int i = 0; i < hightlightTextRegions.Length; i++)
        {
            // region rectangle in PdfPage space
            RectangleF rect = regions[i].Rectangle;

            // convert PDF page space to Image space
            rect = RectFromPdfPageSpaceToImageSpace(rect, page, image);

            hightlightTextRegions[i] = new HightlightRectangle(Rectangle.Round(rect));
        }
        ColoredObjects<HightlightRectangle> objects = new ColoredObjects<HightlightRectangle>(hightlightTextRegions);
        objects.Brush = new SolidBrush(Color.FromArgb(56, Color.Blue));
        objects.Pen = null;
        Items.Clear();
        Items.Add(objects);
    }

    private RectangleF RectFromPdfPageSpaceToImageSpace(RectangleF rect, PdfPage page, VintasoftImage image)
    {
        PointF pt1 = new PointF(rect.X, rect.Y);
        PointF pt2 = new PointF(rect.X + rect.Width, rect.Y + rect.Height);
        page.UnitsToPixels(ref pt1, image.Resolution);
        page.UnitsToPixels(ref pt2, image.Resolution);
        rect.Width = pt2.X - pt1.X;
        rect.Height = pt1.Y - pt2.Y;
        rect.X = pt1.X;
        rect.Y = pt1.Y - rect.Height;
        return rect;
    }

    void ImageViewer_FocusedIndexChanged(object sender, FocusedIndexChangedEventArgs e)
    {
        UpdateItems();
    }

    void ImageViewer_RenderingSettingsChanged(object sender, EventArgs e)
    {
        UpdateItems();
    }
}
Last, you need get all search results, create highlighted objects from results and show highlighted objects:

Code: Select all

public void FindAllAndSelect(string text)
{
    Dictionary<VintasoftImage, TextRegion[]> searchResults = FindAll(imageViewer1.Images, text);
    TextRegionHighlightTool tool = new TextRegionHighlightTool(searchResults);
    imageViewer1.VisualTool = tool;
}

// Search text in all pages.
private Dictionary<VintasoftImage, TextRegion[]> FindAll(ImageCollection images, string text)
{
    Dictionary<VintasoftImage, TextRegion[]> results = new Dictionary<VintasoftImage, TextRegion[]>();
    FindTextOptions options = new FindTextOptions();
    options.MatchCase = false;
    for (int i = 0; i < images.Count; i++)
    {
        PdfPage page = PdfVisualTool.GetPageFromImage(images[i]);
        lock (page.Document)
        {
            List<TextRegion> regions = new List<TextRegion>();
            int charIndex = 0;
            while (true)
            {
                TextRegion region = page.TextRegion.FindText(text, ref charIndex, options);
                charIndex += text.Length;
                if (region != null)
                    regions.Add(region);
                else
                    break;
            }
            results.Add(images[i], regions.ToArray());
        }
    }
    return results;
}

We will simplify this code in version 7.0.

Best regards, Alexander
Post Reply