예제 #1
0
        bool _findAnchor(Template.Anchor a, PointF parentAnchorPoint0, Func <PointF, bool> proceedOnFound)
        {
            if (!a.IsSet())
            {
                return(false);
            }
            RectangleF rectangle = a.Rectangle();
            RectangleF searchRectangle;

            {
                if (a.ParentAnchorId != null)
                {
                    RectangleF pameir = pageCollection.ActiveTemplate.Anchors.Find(x => x.Id == a.ParentAnchorId).Rectangle();
                    rectangle.X += parentAnchorPoint0.X - pameir.X;
                    rectangle.Y += parentAnchorPoint0.Y - pameir.Y;
                }
                if (a.SearchRectangleMargin >= 0)
                {
                    searchRectangle = getSearchRectangle(rectangle, a.SearchRectangleMargin);
                }
                else
                {
                    searchRectangle = new RectangleF();//not used, just stub to compile
                }
            }

            switch (a.Type)
            {
            case Template.Anchor.Types.PdfText:
            {
                Template.Anchor.PdfText pt = (Template.Anchor.PdfText)a;
                List <Template.Anchor.PdfText.CharBox> cbs = pt.CharBoxs;
                if (pt.IgnoreInvisibleChars)
                {
                    cbs = cbs.Where(x => !Pdf.InvisibleCharacters.Contains(x.Char)).ToList();
                }
                if (cbs.Count < 1)
                {
                    int w = (int)(Bitmap.Width * Settings.Constants.Image2PdfResolutionRatio - rectangle.Width);
                    int h = (int)(Bitmap.Height * Settings.Constants.Image2PdfResolutionRatio - rectangle.Height);
                    for (int i = 0; i < w; i++)
                    {
                        for (int j = 0; j < h; j++)
                        {
                            RectangleF actualR = new RectangleF(i, j, rectangle.Width, rectangle.Height);
                            if (PdfCharBoxs.FirstOrDefault(x => actualR.Contains(x.R) && (!pt.IgnoreInvisibleChars || !Pdf.InvisibleCharacters.Contains(x.Char))) == null &&
                                !proceedOnFound(actualR.Location)
                                )
                            {
                                return(true);
                            }
                        }
                    }
                    return(false);
                }
                IEnumerable <Pdf.CharBox> tcb0s;
                if (pt.SearchRectangleMargin < 0)
                {
                    tcb0s = PdfCharBoxs.Where(x => x.Char == cbs[0].Char);
                }
                else
                {
                    tcb0s = PdfCharBoxs.Where(x => x.Char == cbs[0].Char && searchRectangle.Contains(x.R));
                }
                List <Pdf.CharBox> tcbs = new List <Pdf.CharBox>();
                foreach (Pdf.CharBox tcb0 in tcb0s)
                {
                    tcbs.Clear();
                    tcbs.Add(tcb0);
                    for (int i = 1; i < cbs.Count; i++)
                    {
                        PointF p;
                        if (pt.PositionDeviationIsAbsolute)
                        {
                            p = new PointF(tcb0.R.X + cbs[i].Rectangle.X - cbs[0].Rectangle.X, tcb0.R.Y + cbs[i].Rectangle.Y - cbs[0].Rectangle.Y);
                        }
                        else
                        {
                            p = new PointF(tcbs[i - 1].R.X + cbs[i].Rectangle.X - cbs[i - 1].Rectangle.X, tcbs[i - 1].R.Y + cbs[i].Rectangle.Y - cbs[i - 1].Rectangle.Y);
                        }
                        foreach (Pdf.CharBox bt in PdfCharBoxs.Where(x => x.Char == cbs[i].Char))
                        {
                            if (Math.Abs(bt.R.X - p.X) <= pt.PositionDeviation && Math.Abs(bt.R.Y - p.Y) <= pt.PositionDeviation)
                            {
                                tcbs.Add(bt);
                                break;
                            }
                        }
                        if (tcbs.Count - 1 < i)
                        {
                            break;
                        }
                    }
                    if (tcbs.Count == cbs.Count)
                    {
                        SizeF      shift   = new SizeF(tcbs[0].R.X - cbs[0].Rectangle.X, tcbs[0].R.Y - cbs[0].Rectangle.Y);
                        RectangleF actualR = new RectangleF(rectangle.X + shift.Width, rectangle.Y + shift.Height, rectangle.Width, rectangle.Height);
                        if (PdfCharBoxs.FirstOrDefault(x => actualR.Contains(x.R) && !tcbs.Contains(x) && (!pt.IgnoreInvisibleChars || !Pdf.InvisibleCharacters.Contains(x.Char))) == null &&
                            !proceedOnFound(actualR.Location)
                            )
                        {
                            return(true);
                        }
                    }
                }
            }
                return(false);

            case Template.Anchor.Types.OcrText:
            {
                Template.Anchor.OcrText ot = (Template.Anchor.OcrText)a;
                List <Template.Anchor.OcrText.CharBox> cbs = ot.CharBoxs;
                if (cbs.Count < 1)
                {
                    int w = (int)(ActiveTemplateBitmap.Width * Settings.Constants.Image2PdfResolutionRatio - rectangle.Width);
                    int h = (int)(ActiveTemplateBitmap.Height * Settings.Constants.Image2PdfResolutionRatio - rectangle.Height);
                    for (int i = 0; i < w; i++)
                    {
                        for (int j = 0; j < h; j++)
                        {
                            RectangleF actualR = new RectangleF(i, j, rectangle.Width, rectangle.Height);
                            if (ActiveTemplateOcrCharBoxs.FirstOrDefault(x => actualR.Contains(x.R)) == null &&
                                !proceedOnFound(actualR.Location)
                                )
                            {
                                return(true);
                            }
                        }
                    }
                    return(false);
                }
                List <Ocr.CharBox>        contaningOcrCharBoxs;
                PointF                    searchRectanglePosition = new PointF(0, 0);
                IEnumerable <Ocr.CharBox> tcb0s;
                if (ot.OcrEntirePage)
                {
                    contaningOcrCharBoxs = ActiveTemplateOcrCharBoxs;
                    if (ot.SearchRectangleMargin < 0)
                    {
                        tcb0s = contaningOcrCharBoxs.Where(x => x.Char == cbs[0].Char);
                    }
                    else
                    {
                        tcb0s = contaningOcrCharBoxs.Where(x => x.Char == cbs[0].Char && searchRectangle.Contains(x.R));
                    }
                }
                else if (ot.SearchRectangleMargin < 0)
                {
                    contaningOcrCharBoxs = ActiveTemplateOcrCharBoxs;
                    tcb0s = contaningOcrCharBoxs.Where(x => x.Char == cbs[0].Char);
                }
                else
                {
                    RectangleF contaningRectangle = searchRectangle;
                    for (int i = 1; i < ot.CharBoxs.Count; i++)
                    {
                        contaningRectangle = RectangleF.Union(contaningRectangle, getSearchRectangle(ot.CharBoxs[i].Rectangle.GetSystemRectangleF(), a.SearchRectangleMargin));
                    }
                    contaningOcrCharBoxs    = Ocr.This.GetCharBoxs(GetRectangleFromActiveTemplateBitmap(contaningRectangle.X / Settings.Constants.Image2PdfResolutionRatio, contaningRectangle.Y / Settings.Constants.Image2PdfResolutionRatio, contaningRectangle.Width / Settings.Constants.Image2PdfResolutionRatio, contaningRectangle.Height / Settings.Constants.Image2PdfResolutionRatio));
                    searchRectanglePosition = new PointF(contaningRectangle.X < 0 ? 0 : contaningRectangle.X, contaningRectangle.Y < 0 ? 0 : contaningRectangle.Y);
                    RectangleF unshiftedMainElementSearchRectangle = new RectangleF(searchRectangle.X - searchRectanglePosition.X, searchRectangle.Y - searchRectanglePosition.Y, searchRectangle.Width, searchRectangle.Height);
                    tcb0s = contaningOcrCharBoxs.Where(x => x.Char == cbs[0].Char && unshiftedMainElementSearchRectangle.Contains(x.R));
                }
                List <Ocr.CharBox> tcbs = new List <Ocr.CharBox>();
                foreach (Ocr.CharBox tcb0 in tcb0s)
                {
                    tcbs.Clear();
                    tcbs.Add(tcb0);
                    for (int i = 1; i < cbs.Count; i++)
                    {
                        PointF p;
                        if (ot.PositionDeviationIsAbsolute)
                        {
                            p = new PointF(tcb0.R.X + cbs[i].Rectangle.X - cbs[0].Rectangle.X, tcb0.R.Y + cbs[i].Rectangle.Y - cbs[0].Rectangle.Y);
                        }
                        else
                        {
                            p = new PointF(tcbs[i - 1].R.X + cbs[i].Rectangle.X - cbs[i - 1].Rectangle.X, tcbs[i - 1].R.Y + cbs[i].Rectangle.Y - cbs[i - 1].Rectangle.Y);
                        }
                        foreach (Ocr.CharBox bt in contaningOcrCharBoxs.Where(x => x.Char == cbs[i].Char))
                        {
                            if (Math.Abs(bt.R.X - p.X) <= ot.PositionDeviation && Math.Abs(bt.R.Y - p.Y) <= ot.PositionDeviation)
                            {
                                tcbs.Add(bt);
                                break;
                            }
                        }
                        if (tcbs.Count - 1 < i)
                        {
                            break;
                        }
                    }
                    if (tcbs.Count == cbs.Count)
                    {
                        SizeF      shift   = new SizeF(tcbs[0].R.X - cbs[0].Rectangle.X, tcbs[0].R.Y - cbs[0].Rectangle.Y);
                        RectangleF actualR = new RectangleF(rectangle.X + shift.Width, rectangle.Y + shift.Height, rectangle.Width, rectangle.Height);
                        if (contaningOcrCharBoxs.FirstOrDefault(x => actualR.Contains(x.R) && !tcbs.Contains(x)) == null &&
                            !proceedOnFound(actualR.Location)
                            )
                        {
                            return(true);
                        }
                    }
                }
            }
                return(false);

            case Template.Anchor.Types.ImageData:
            {
                Template.Anchor.ImageData idv = (Template.Anchor.ImageData)a;
                Point     searchRectanglePosition;
                ImageData id0;
                if (idv.SearchRectangleMargin < 0)
                {
                    id0 = ActiveTemplateImageData;
                    searchRectanglePosition = new Point(0, 0);
                }
                else
                {
                    searchRectanglePosition = new Point(searchRectangle.X < 0 ? 0 : (int)searchRectangle.X, searchRectangle.Y < 0 ? 0 : (int)searchRectangle.Y);
                    id0 = new ImageData(GetRectangleFromActiveTemplateBitmap(searchRectangle.X / Settings.Constants.Image2PdfResolutionRatio, searchRectangle.Y / Settings.Constants.Image2PdfResolutionRatio, searchRectangle.Width / Settings.Constants.Image2PdfResolutionRatio, searchRectangle.Height / Settings.Constants.Image2PdfResolutionRatio));
                }
                Point?p_ = idv.Image.FindWithinImage(id0, idv.BrightnessTolerance, idv.DifferentPixelNumberTolerance, idv.FindBestImageMatch);
                if (p_ == null)
                {
                    return(false);
                }
                Point p = (Point)p_;
                return(!proceedOnFound(new PointF(searchRectanglePosition.X + p.X, searchRectanglePosition.Y + p.Y)));
            }

            default:
                throw new Exception("Unknown option: " + a.Type);
            }
        }
        bool findAnchor(Template.Anchor a, PointF parentAnchorPoint0, Func <PointF, bool> findNext)
        {
            if (!a.IsSet())
            {
                return(false);
            }
            RectangleF rectangle = a.Rectangle();
            RectangleF searchRectangle;

            {
                if (a.ParentAnchorId != null)
                {
                    RectangleF pameir = PageCollection.ActiveTemplate.Anchors.Find(x => x.Id == a.ParentAnchorId).Rectangle();
                    rectangle.X += parentAnchorPoint0.X - pameir.X;
                    rectangle.Y += parentAnchorPoint0.Y - pameir.Y;
                }
                if (a.SearchRectangleMargin >= 0)
                {
                    searchRectangle = getSearchRectangle(rectangle, a.SearchRectangleMargin);
                }
                else
                {
                    searchRectangle = new RectangleF();//not used, just stub to compile
                }
            }

            switch (a.Type)
            {
            case Template.Anchor.Types.PdfText:
            {
                Template.Anchor.PdfText pt = (Template.Anchor.PdfText)a;
                List <Template.Anchor.PdfText.CharBox> cbs = pt.CharBoxs;
                if (pt.IgnoreInvisibleChars)
                {
                    cbs = cbs.Where(x => !Pdf.InvisibleCharacters.Contains(x.Char)).ToList();
                }
                if (cbs.Count < 1)
                {
                    int w = Size.Width;
                    int h = Size.Height;
                    for (int i = 0; i < w; i++)
                    {
                        for (int j = 0; j < h; j++)
                        {
                            RectangleF actualR = new RectangleF(i, j, rectangle.Width, rectangle.Height);
                            if (        //check that the rectangle contains nothing
                                PdfCharBoxs.FirstOrDefault(x => actualR.Contains(x.R) && (!pt.IgnoreInvisibleChars || !Pdf.InvisibleCharacters.Contains(x.Char))) == null &&
                                !findNext(actualR.Location)
                                )
                            {
                                return(true);
                            }
                        }
                    }
                    return(false);
                }
                IEnumerable <Pdf.CharBox> tcb0s;
                if (pt.SearchRectangleMargin < 0)
                {
                    tcb0s = PdfCharBoxs.Where(x => x.Char == cbs[0].Char);
                }
                else
                {
                    tcb0s = PdfCharBoxs.Where(x => x.Char == cbs[0].Char && searchRectangle.Contains(x.R));
                }
                List <Pdf.CharBox> tcbs = new List <Pdf.CharBox>();
                foreach (Pdf.CharBox tcb0 in tcb0s)
                {
                    tcbs.Clear();
                    tcbs.Add(tcb0);
                    for (int i = 1; i < cbs.Count; i++)
                    {
                        PointF p;
                        if (pt.PositionDeviationIsAbsolute)
                        {
                            p = new PointF(tcb0.R.X + cbs[i].Rectangle.X - cbs[0].Rectangle.X, tcb0.R.Y + cbs[i].Rectangle.Y - cbs[0].Rectangle.Y);
                        }
                        else
                        {
                            p = new PointF(tcbs[i - 1].R.X + cbs[i].Rectangle.X - cbs[i - 1].Rectangle.X, tcbs[i - 1].R.Y + cbs[i].Rectangle.Y - cbs[i - 1].Rectangle.Y);
                        }
                        foreach (Pdf.CharBox bt in PdfCharBoxs.Where(x => x.Char == cbs[i].Char))
                        {
                            if (Math.Abs(bt.R.X - p.X) <= pt.PositionDeviation && Math.Abs(bt.R.Y - p.Y) <= pt.PositionDeviation)
                            {
                                tcbs.Add(bt);
                                break;
                            }
                        }
                        if (tcbs.Count - 1 < i)
                        {
                            break;
                        }
                    }
                    if (tcbs.Count == cbs.Count)
                    {
                        SizeF      shift   = new SizeF(tcbs[0].R.X - cbs[0].Rectangle.X, tcbs[0].R.Y - cbs[0].Rectangle.Y);
                        RectangleF actualR = new RectangleF(rectangle.X + shift.Width, rectangle.Y + shift.Height, rectangle.Width, rectangle.Height);
                        if (        //check that the found rectangle contains only the anchor's boxes
                            (pt.IgnoreOtherCharsInRectangle || PdfCharBoxs.FirstOrDefault(x => actualR.Contains(x.R) && !tcbs.Contains(x) && (!pt.IgnoreInvisibleChars || !Pdf.InvisibleCharacters.Contains(x.Char))) == null) &&
                            !findNext(actualR.Location)
                            )
                        {
                            return(true);
                        }
                    }
                }
            }
                return(false);

            case Template.Anchor.Types.OcrText:
            {
                Template.Anchor.OcrText ot = (Template.Anchor.OcrText)a;
                List <Template.Anchor.OcrText.CharBox> cbs = ot.CharBoxs;
                if (cbs.Count < 1)
                {
                    int w = (int)(ActiveTemplateBitmap.Width * Settings.Constants.Pdf2ImageResolutionRatio - rectangle.Width);
                    int h = (int)(ActiveTemplateBitmap.Height * Settings.Constants.Pdf2ImageResolutionRatio - rectangle.Height);
                    for (int i = 0; i < w; i++)
                    {
                        for (int j = 0; j < h; j++)
                        {
                            RectangleF actualR = new RectangleF(i, j, rectangle.Width, rectangle.Height);
                            if (ActiveTemplateOcrCharBoxs.FirstOrDefault(x => actualR.Contains(x.R)) == null &&
                                !findNext(actualR.Location)
                                )
                            {
                                return(true);
                            }
                        }
                    }
                    return(false);
                }
                List <Ocr.CharBox>        searchRectangleOcrCharBoxs;
                IEnumerable <Ocr.CharBox> tcb0s;
                if (ot.OcrEntirePage)
                {
                    searchRectangleOcrCharBoxs = ActiveTemplateOcrCharBoxs;
                    if (ot.SearchRectangleMargin < 0)
                    {
                        tcb0s = searchRectangleOcrCharBoxs.Where(x => x.Char == cbs[0].Char);
                    }
                    else
                    {
                        tcb0s = searchRectangleOcrCharBoxs.Where(x => x.Char == cbs[0].Char && searchRectangle.Contains(x.R));
                    }
                }
                else if (ot.SearchRectangleMargin < 0)
                {
                    searchRectangleOcrCharBoxs = ActiveTemplateOcrCharBoxs;
                    tcb0s = searchRectangleOcrCharBoxs.Where(x => x.Char == cbs[0].Char);
                }
                else
                {
                    //RectangleF contaningRectangle = searchRectangle;
                    //for (int i = 1; i < ot.CharBoxs.Count; i++)
                    //    contaningRectangle = RectangleF.Union(contaningRectangle, getSearchRectangle(ot.CharBoxs[i].Rectangle.GetSystemRectangleF(), a.SearchRectangleMargin));
                    //searchRectangleOcrCharBoxs = Ocr.This.GetCharBoxs(GetRectangleFromActiveTemplateBitmap(contaningRectangle.X / Settings.Constants.Pdf2ImageResolutionRatio, contaningRectangle.Y / Settings.Constants.Pdf2ImageResolutionRatio, contaningRectangle.Width / Settings.Constants.Pdf2ImageResolutionRatio, contaningRectangle.Height / Settings.Constants.Pdf2ImageResolutionRatio));
                    //PointF searchRectanglePosition = new PointF(contaningRectangle.X < 0 ? 0 : contaningRectangle.X, contaningRectangle.Y < 0 ? 0 : contaningRectangle.Y);
                    //searchRectangleOcrCharBoxs.ForEach(x => { x.R.X += contaningRectangle.X; x.R.Y += contaningRectangle.Y; });
                    //RectangleF mainElementSearchRectangle = new RectangleF(searchRectangle.X - searchRectanglePosition.X, searchRectangle.Y - searchRectanglePosition.Y, searchRectangle.Width, searchRectangle.Height);
                    //tcb0s = searchRectangleOcrCharBoxs.Where(x => x.Char == cbs[0].Char && contaningRectangle.Contains(x.R));
                    using (Bitmap b = GetRectangleFromActiveTemplateBitmap(searchRectangle.X / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Y / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Width / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Height / Settings.Constants.Pdf2ImageResolutionRatio))
                    {
                        if (b == null)
                        {
                            return(false);
                        }
                        searchRectangleOcrCharBoxs = Ocr.This.GetCharBoxs(b, PageCollection.ActiveTemplate.TesseractPageSegMode);
                    }
                    PointF searchRectanglePosition = new PointF(searchRectangle.X < 0 ? 0 : searchRectangle.X, searchRectangle.Y < 0 ? 0 : searchRectangle.Y);
                    searchRectangleOcrCharBoxs.ForEach(x => { x.R.X += searchRectanglePosition.X; x.R.Y += searchRectanglePosition.Y; });
                    tcb0s = searchRectangleOcrCharBoxs.Where(x => x.Char == cbs[0].Char && searchRectangle.Contains(x.R));
                }
                List <Ocr.CharBox> tcbs = new List <Ocr.CharBox>();
                foreach (Ocr.CharBox tcb0 in tcb0s)
                {
                    tcbs.Clear();
                    tcbs.Add(tcb0);
                    for (int i = 1; i < cbs.Count; i++)
                    {
                        PointF p;
                        if (ot.PositionDeviationIsAbsolute)
                        {
                            p = new PointF(tcb0.R.X + cbs[i].Rectangle.X - cbs[0].Rectangle.X, tcb0.R.Y + cbs[i].Rectangle.Y - cbs[0].Rectangle.Y);
                        }
                        else
                        {
                            p = new PointF(tcbs[i - 1].R.X + cbs[i].Rectangle.X - cbs[i - 1].Rectangle.X, tcbs[i - 1].R.Y + cbs[i].Rectangle.Y - cbs[i - 1].Rectangle.Y);
                        }
                        foreach (Ocr.CharBox bt in searchRectangleOcrCharBoxs.Where(x => x.Char == cbs[i].Char))
                        {
                            if (Math.Abs(bt.R.X - p.X) <= ot.PositionDeviation && Math.Abs(bt.R.Y - p.Y) <= ot.PositionDeviation)
                            {
                                tcbs.Add(bt);
                                break;
                            }
                        }
                        if (tcbs.Count - 1 < i)
                        {
                            break;
                        }
                    }
                    if (tcbs.Count == cbs.Count)
                    {
                        SizeF      shift   = new SizeF(tcbs[0].R.X - cbs[0].Rectangle.X, tcbs[0].R.Y - cbs[0].Rectangle.Y);
                        RectangleF actualR = new RectangleF(rectangle.X + shift.Width, rectangle.Y + shift.Height, rectangle.Width, rectangle.Height);
                        if (        //check that the found rectangle contains only the anchor's boxes
                            searchRectangleOcrCharBoxs.FirstOrDefault(x => actualR.Contains(x.R) && !tcbs.Contains(x)) == null &&
                            !findNext(actualR.Location)
                            )
                        {
                            return(true);
                        }
                    }
                }
            }
                return(false);

            case Template.Anchor.Types.ImageData:
            {
                Template.Anchor.ImageData idv = (Template.Anchor.ImageData)a;
                Point     searchRectanglePosition;
                ImageData id0;
                if (idv.SearchRectangleMargin < 0)
                {
                    id0 = ActiveTemplateImageData;
                    searchRectanglePosition = new Point(0, 0);
                }
                else
                {
                    searchRectanglePosition = new Point(searchRectangle.X < 0 ? 0 : (int)searchRectangle.X, searchRectangle.Y < 0 ? 0 : (int)searchRectangle.Y);
                    using (Bitmap b = GetRectangleFromActiveTemplateBitmap(searchRectangle.X / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Y / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Width / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Height / Settings.Constants.Pdf2ImageResolutionRatio))
                    {
                        if (b == null)
                        {
                            return(false);
                        }
                        id0 = new ImageData(b);
                    }
                }
                Point?p_ = idv.Image.FindWithinImage(id0, idv.BrightnessTolerance, idv.DifferentPixelNumberTolerance, idv.FindBestImageMatch);
                if (p_ == null)
                {
                    return(false);
                }
                Point p = (Point)p_;
                return(!findNext(new PointF(searchRectanglePosition.X + p.X, searchRectanglePosition.Y + p.Y)));
            }

            case Template.Anchor.Types.CvImage:
            {
                Template.Anchor.CvImage civ = (Template.Anchor.CvImage)a;
                Point   searchRectanglePosition;
                CvImage ci0;
                if (civ.SearchRectangleMargin < 0)
                {
                    ci0 = ActiveTemplateCvImage;
                    searchRectanglePosition = new Point(0, 0);
                }
                else
                {
                    searchRectanglePosition = new Point(searchRectangle.X < 0 ? 0 : (int)searchRectangle.X, searchRectangle.Y < 0 ? 0 : (int)searchRectangle.Y);
                    using (Bitmap b = GetRectangleFromActiveTemplateBitmap(searchRectangle.X / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Y / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Width / Settings.Constants.Pdf2ImageResolutionRatio, searchRectangle.Height / Settings.Constants.Pdf2ImageResolutionRatio))
                    {
                        if (b == null)
                        {
                            return(false);
                        }
                        ci0 = new CvImage(b);
                    }
                }
                if (civ.FindBestImageMatch)
                {
                    //CvImage.Match m = civ.Image.FindFirstMatchWithinImage(ci0, civ.Threshold, civ.ScaleDeviation, PageCollection.ActiveTemplate.CvImageScalePyramidStep);
                    CvImage.Match m = civ.Image.FindBestMatchWithinImage(ci0, civ.Threshold, civ.ScaleDeviation, PageCollection.ActiveTemplate.CvImageScalePyramidStep);
                    if (m == null)
                    {
                        return(false);
                    }
                    Point p = m.Rectangle.Location;
                    return(!findNext(new PointF(searchRectanglePosition.X + p.X, searchRectanglePosition.Y + p.Y)));
                }
                else
                {        //!!!this returns rather the first match than the best match
                    bool found = false;
                    civ.Image.FindMatchesWithinImage(ci0, civ.Threshold, civ.ScaleDeviation, PageCollection.ActiveTemplate.CvImageScalePyramidStep,
                                                     (CvImage.Match m) =>
                        {
                            found = !findNext(new PointF(searchRectanglePosition.X + m.Rectangle.X, searchRectanglePosition.Y + m.Rectangle.Y));
                            return(!found);
                        }
                                                     );
                    return(found);
                }
            }

            default:
                throw new Exception("Unknown option: " + a.Type);
            }
        }