internal AnchorActualInfo GetAnchorActualInfo(int anchorId) { Template.Anchor a = pageCollection.ActiveTemplate.Anchors.Find(x => x.Id == anchorId); if (a == null) { throw new Exception("Anchor[id=" + anchorId + "] does not exist."); } if (!a.IsSet()) { throw new Exception("Anchor[id=" + anchorId + "] is not set."); } StringBuilder sb = new StringBuilder(Serialization.Json.Serialize(a, false)); for (int?id = a.ParentAnchorId; id != null;) { Template.Anchor pa = pageCollection.ActiveTemplate.Anchors.Find(x => x.Id == id); sb.Append(Serialization.Json.Serialize(pa, false)); id = pa.ParentAnchorId; } string sa = sb.ToString(); if (!anchorHashes2anchorActualInfo.TryGetValue(sa, out AnchorActualInfo anchorActualInfo)) { anchorActualInfo = new AnchorActualInfo(a, this); anchorHashes2anchorActualInfo[sa] = anchorActualInfo; } return(anchorActualInfo); }
void _setAnchorStatus(int anchorId) { Template.Anchor a = getAnchor(anchorId, out DataGridViewRow row); if (a == null || row == null) { return; } if (pages == null) { return; } pages.ActiveTemplate = getTemplateFromUI(false); a = pages.ActiveTemplate.Anchors.FirstOrDefault(x => x.Id == anchorId); if (a == null) { throw new Exception("Anchor[Id=" + a.Id + "] does not exist."); } bool set = true; for (Template.Anchor a_ = a; a_ != null; a_ = pages.ActiveTemplate.Anchors.FirstOrDefault(x => x.Id == a_.ParentAnchorId)) { if (!a_.IsSet()) { set = false; getAnchor(a_.Id, out DataGridViewRow r_); setRowStatus(statuses.WARNING, r_, "Not set"); } } if (!set) { return; } Page.AnchorActualInfo aai = pages[currentPageI].GetAnchorActualInfo(a.Id); getAnchor(a.Id, out DataGridViewRow r); if (!aai.Found) { setRowStatus(statuses.ERROR, r, "Not found"); } else { setRowStatus(statuses.SUCCESS, r, "Found"); } }
//internal AnchorActualInfo GetAnchorActualInfo(int anchorId) //{ // Template.Anchor a = PageCollection.ActiveTemplate.Anchors.Find(x => x.Id == anchorId); // if (a == null) // throw new Exception("Anchor[id=" + anchorId + "] does not exist."); // if (!a.IsSet()) // throw new Exception("Anchor[id=" + anchorId + "] is not set."); // StringBuilder sb = new StringBuilder(Serialization.Json.Serialize(a, false)); // for (int? id = a.ParentAnchorId; id != null;) // { // Template.Anchor pa = PageCollection.ActiveTemplate.Anchors.Find(x => x.Id == id); // sb.Append(Serialization.Json.Serialize(pa, false)); // id = pa.ParentAnchorId; // } // string sa = sb.ToString(); // if (!anchorHashes2anchorActualInfo.TryGetValue(sa, out AnchorActualInfo anchorActualInfo)) // { // anchorActualInfo = new AnchorActualInfo(a, this); // anchorHashes2anchorActualInfo[sa] = anchorActualInfo; // } // return anchorActualInfo; //} //Dictionary<string, AnchorActualInfo> anchorHashes2anchorActualInfo = new Dictionary<string, AnchorActualInfo>(); internal AnchorActualInfo GetAnchorActualInfo(int anchorId) { Template.Anchor a = PageCollection.ActiveTemplate.Anchors.Find(x => x.Id == anchorId); if (a == null) { throw new Exception("Anchor[id=" + anchorId + "] does not exist."); } if (!a.IsSet()) { throw new Exception("Anchor[id=" + anchorId + "] is not set."); } if (!anchorIds2anchorActualInfo.TryGetValue(a.Id, out AnchorActualInfo anchorActualInfo)) { anchorActualInfo = new AnchorActualInfo(a, this); anchorIds2anchorActualInfo[a.Id] = anchorActualInfo; } return(anchorActualInfo); }
internal Template GetTemplateFromUI(bool saving) { Template t = new Template(); if (saving && string.IsNullOrWhiteSpace(name.Text)) { throw new Exception("Name is empty!"); } t.Name = name.Text.Trim(); t.TextAutoInsertSpace = new TextAutoInsertSpace { Threshold = (float)textAutoInsertSpaceThreshold.Value, Representative = Regex.Unescape(textAutoInsertSpaceRepresentative.Text), }; t.CvImageScalePyramidStep = (int)CvImageScalePyramidStep.Value; t.TesseractPageSegMode = (Tesseract.PageSegMode)TesseractPageSegMode.SelectedItem; if (SingleFieldFromFieldImage.Checked) { t.FieldOcrMode |= Template.FieldOcrModes.SingleFieldFromFieldImage; } else { t.FieldOcrMode &= ~Template.FieldOcrModes.SingleFieldFromFieldImage; } if (ColumnFieldFromFieldImage.Checked) { t.FieldOcrMode |= Template.FieldOcrModes.ColumnFieldFromFieldImage; } else { t.FieldOcrMode &= ~Template.FieldOcrModes.ColumnFieldFromFieldImage; } bitmapPreparationForm.SetTemplate(t); bool? removeNotLinkedAnchors = null; List <int> conditionAnchorIds = null; if (saving) { conditionAnchorIds = new List <int>(); foreach (DataGridViewRow r in conditions.Rows) { Template.Condition c = (Template.Condition)r.Tag; if (c != null && c.IsSet()) { conditionAnchorIds.AddRange(BooleanEngine.GetAnchorIds(c.Value)); } } conditionAnchorIds = conditionAnchorIds.Distinct().ToList(); } t.Anchors = new List <Template.Anchor>(); foreach (DataGridViewRow r in anchors.Rows) { Template.Anchor a = (Template.Anchor)r.Tag; if (a == null) { continue; } if (saving) { if (!a.IsSet()) { throw new Exception("Anchor[Id=" + a.Id + "] is not set!"); } if (!conditionAnchorIds.Contains(a.Id)) { bool engaged = false; foreach (DataGridViewRow rr in anchors.Rows) { Template.Anchor a_ = (Template.Anchor)rr.Tag; if (a_ == null) { continue; } if (a_.ParentAnchorId == a.Id) { engaged = true; break; } } if (!engaged) { foreach (DataGridViewRow rr in fields.Rows) { Template.Field m = (Template.Field)rr.Tag; if (m != null && (m.LeftAnchor?.Id == a.Id || m.TopAnchor?.Id == a.Id || m.RightAnchor?.Id == a.Id || m.BottomAnchor?.Id == a.Id)) { engaged = true; break; } } if (!engaged) { if (a.Id != t.ScalingAnchorId) { if (removeNotLinkedAnchors == null) { removeNotLinkedAnchors = Message.YesNo("The template contains not linked anchor[s]. Remove them?"); } if (removeNotLinkedAnchors == true) { continue; } } } } } } t.Anchors.Add((Template.Anchor)Serialization.Json.Clone2(a)); } t.Anchors = t.Anchors.OrderBy(a => a.Id).ToList(); if (saving) { t.GetScalingAnchor();//check is it is correct; } t.Conditions = new List <Template.Condition>(); foreach (DataGridViewRow r in conditions.Rows) { Template.Condition c = (Template.Condition)r.Tag; if (c == null) { continue; } if (saving) { if (!c.IsSet()) { throw new Exception("Condition[name=" + c.Name + "] is not set!"); } BooleanEngine.Check(c.Value, t.Anchors.Select(x => x.Id)); } t.Conditions.Add(Serialization.Json.Clone(c)); } if (saving) { var dcs = t.Conditions.GroupBy(x => x.Name).Where(x => x.Count() > 1).FirstOrDefault(); if (dcs != null) { throw new Exception("Condition '" + dcs.First().Name + "' is duplicated!"); } } t.Fields = new List <Template.Field>(); foreach (DataGridViewRow r in fields.Rows) { Template.Field f = (Template.Field)r.Tag; if (f == null) { continue; } if (saving && !f.IsSet()) { throw new Exception("Field[" + r.Index + "] is not set!"); } if (saving) { foreach (int?ai in new List <int?> { f.LeftAnchor?.Id, f.TopAnchor?.Id, f.RightAnchor?.Id, f.BottomAnchor?.Id }) { if (ai != null && t.Anchors.FirstOrDefault(x => x.Id == ai) == null) { throw new Exception("Anchor[Id=" + ai + " does not exist."); } } } t.Fields.Add(Serialization.Json.Clone(f)); } if (saving) { if (t.Fields.Count < 1) { throw new Exception("Fields is empty!"); } //var dfs = t.Fields.GroupBy(x => x.Name).Where(x => x.Count() > 1).FirstOrDefault(); //if (dfs != null) // throw new Exception("Field '" + dfs.First().Name + "' is duplicated!"); //foreach (string columnOfTable in t.Fields.Where(x => x is Template.Field.PdfText).Select(x => (Template.Field.PdfText)x).Where(x => x.ColumnOfTable != null).Select(x => x.ColumnOfTable)) //{ // Dictionary<string, List<Template.Field>> fieldName2orderedFields = new Dictionary<string, List<Template.Field>>(); // foreach (Template.Field.PdfText pt in t.Fields.Where(x => x is Template.Field.PdfText).Select(x => (Template.Field.PdfText)x).Where(x => x.ColumnOfTable == columnOfTable)) // { // List<Template.Field> fs; // if (!fieldName2orderedFields.TryGetValue(pt.Name, out fs)) // { // fs = new List<Template.Field>(); // fieldName2orderedFields[pt.Name] = fs; // } // fs.Add(pt); // } // int definitionCount = fieldName2orderedFields.Max(x => x.Value.Count()); // foreach (string fn in fieldName2orderedFields.Keys) // if (definitionCount > fieldName2orderedFields[fn].Count) // throw new Exception("Field '" + fn + "' is column of table " + columnOfTable + " and so it must have the same number of definitions as the rest column fields!"); //} //foreach (Template.Field f0 in t.Fields) //{ // int tableDefinitionsCount = t.Fields.Where(x => x.Name == f0.Name).Count(); // string fn = t.Fields.Where(x => x.ColumnOfTable == f0.Name).GroupBy(x => x.Name).Where(x => x.Count() > tableDefinitionsCount).FirstOrDefault()?.First().Name; // if (fn != null) // throw new Exception("Field '" + fn + "' is a column of table field " + f0.Name + " so " + f0.Name + " must have number of definitions not less then that of " + fn + "."); //} //it is done only to avoid unneeded OCR //string fn = t.Fields.Where(x => x.ColumnOfTable != null && (x.DefaultValueType != Template.Field.ValueTypes.PdfText && x.DefaultValueType != Template.Field.ValueTypes.PdfTextLines)).FirstOrDefault()?.Name; //if (fn != null) // throw new Exception("Field '" + fn + "' is a column of a table field. Its default value type can be either " + Template.Field.ValueTypes.PdfText + " or " + Template.Field.ValueTypes.PdfTextLines); } if (saving) { t.Editor = new Template.EditorSettings { TestFile = testFile.Text, TestPictureScale = pictureScale.Value, ExtractFieldsAutomaticallyWhenPageChanged = ExtractFieldsAutomaticallyWhenPageChanged.Checked, ShowFieldTextLineSeparators = ShowFieldTextLineSeparators.Checked, CheckConditionsAutomaticallyWhenPageChanged = CheckConditionsAutomaticallyWhenPageChanged.Checked, }; } return(t); }
bool findAndDrawAnchor(int anchorId) { if (pages == null) { return(false); } pages.ActiveTemplate = getTemplateFromUI(false); Template.Anchor a = pages.ActiveTemplate.Anchors.FirstOrDefault(x => x.Id == anchorId); if (a == null) { throw new Exception("Anchor[Id=" + a.Id + "] does not exist."); } bool set = true; for (Template.Anchor a_ = a; a_ != null; a_ = pages.ActiveTemplate.Anchors.FirstOrDefault(x => x.Id == a_.ParentAnchorId)) { if (a != a_) { showAnchorRowAs(a_.Id, rowStates.Parent, false); } if (!a_.IsSet()) { set = false; getAnchor(a_.Id, out DataGridViewRow r_); setRowStatus(statuses.WARNING, r_, "Not set"); } } if (!set) { return(false); } getAnchor(a.Id, out DataGridViewRow r); if (!pages[currentPageI].GetAnchorActualInfo(a.Id).Found) { setRowStatus(statuses.ERROR, r, "Not found"); return(false); } setRowStatus(statuses.SUCCESS, r, "Found"); for (Template.Anchor a_ = a; a_ != null; a_ = pages.ActiveTemplate.Anchors.FirstOrDefault(x => x.Id == a_.ParentAnchorId)) { SizeF shift = pages[currentPageI].GetAnchorActualInfo(a_.Id).Shift; RectangleF r_ = a_.Rectangle(); r_.X += shift.Width; r_.Y += shift.Height; if (a_ == a) { if (currentAnchorControl != null) { drawBoxes(Settings.Appearance.SelectionBoxColor, Settings.Appearance.SelectionBoxBorderWidth, new List <RectangleF> { r_ }); owners2resizebleBox[a_] = new ResizebleBox(a_, r_, Settings.Appearance.SelectionBoxBorderWidth); } else { drawBoxes(Settings.Appearance.AnchorBoxColor, Settings.Appearance.AnchorBoxBorderWidth, new List <RectangleF> { r_ }); } } else { drawBoxes(Settings.Appearance.AscendantAnchorBoxColor, Settings.Appearance.AscendantAnchorBoxBorderWidth, new List <RectangleF> { r_ }); } List <RectangleF> bs = null; switch (a_.Type) { case Template.Anchor.Types.PdfText: { var pt = (Template.Anchor.PdfText)a_; bs = pt.CharBoxs.Select(x => new RectangleF(x.Rectangle.X + shift.Width, x.Rectangle.Y + shift.Height, x.Rectangle.Width, x.Rectangle.Height)).ToList(); } break; case Template.Anchor.Types.OcrText: { var ot = (Template.Anchor.OcrText)a_; bs = ot.CharBoxs.Select(x => new RectangleF(x.Rectangle.X + shift.Width, x.Rectangle.Y + shift.Height, x.Rectangle.Width, x.Rectangle.Height)).ToList(); } break; case Template.Anchor.Types.ImageData: //bs = new List<System.Drawing.RectangleF> { rs[0] }; break; case Template.Anchor.Types.CvImage: //bs = new List<System.Drawing.RectangleF> { rs[0] }; break; default: throw new Exception("Unknown option: " + a_.Type); } if (bs != null) { if (a_ == a) { drawBoxes(Settings.Appearance.AnchorBoxColor, Settings.Appearance.AnchorBoxBorderWidth, bs); } else { drawBoxes(Settings.Appearance.AscendantAnchorBoxColor, Settings.Appearance.AscendantAnchorBoxBorderWidth, bs); } } } return(true); }
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); } }
internal Template GetTemplateFromUI(bool saving) { Template t = new Template(); if (saving && string.IsNullOrWhiteSpace(name.Text)) { throw new Exception("Name is empty!"); } t.Name = name.Text.Trim(); t.TextAutoInsertSpace = new TextAutoInsertSpace { Threshold = (float)textAutoInsertSpace_Threshold.Value, IgnoreSourceSpaces = textAutoInsertSpace_IgnoreSourceSpaces.Checked, //Representative//default }; t.TesseractPageSegMode = (Tesseract.PageSegMode)TesseractPageSegMode.SelectedItem; t.AdjustLineBorders = AdjustLineBorders.Checked; t.SingleFieldFromFieldImage = SingleFieldFromFieldImage.Checked; t.ColumnCellFromCellImage = ColumnCellFromCellImage.Checked; if (CharSizeFilterMinWidth.Value > 0 || CharSizeFilterMaxWidth.Value > 0 || CharSizeFilterMinHeight.Value > 0 || CharSizeFilterMaxHeight.Value > 0) { t.CharFilter = new CharFilter { MinWidth = (float)CharSizeFilterMinWidth.Value, MaxWidth = (float)CharSizeFilterMaxWidth.Value, MinHeight = (float)CharSizeFilterMinHeight.Value, MaxHeight = (float)CharSizeFilterMaxHeight.Value } } ; if (LinePaddingY.Value > 0) { t.LinePaddingY = (int)LinePaddingY.Value; } bitmapPreparationForm.SetTemplate(t); bool? removeNotLinkedAnchors = null; List <int> conditionAnchorIds = null; if (saving) { conditionAnchorIds = new List <int>(); foreach (DataGridViewRow r in conditions.Rows) { Template.Condition c = (Template.Condition)r.Tag; if (c != null && c.IsSet()) { conditionAnchorIds.AddRange(BooleanEngine.GetAnchorIds(c.Value)); } } conditionAnchorIds = conditionAnchorIds.Distinct().ToList(); } t.Anchors = new List <Template.Anchor>(); foreach (DataGridViewRow r in anchors.Rows) { Template.Anchor a = (Template.Anchor)r.Tag; if (a == null) { continue; } if (saving) { if (!a.IsSet()) { throw new Exception("Anchor[Id=" + a.Id + "] is not set!"); } if (!conditionAnchorIds.Contains(a.Id)) { bool engaged = false; foreach (DataGridViewRow rr in anchors.Rows) { Template.Anchor a_ = (Template.Anchor)rr.Tag; if (a_ == null) { continue; } if (a_.ParentAnchorId == a.Id) { engaged = true; break; } } if (!engaged) { foreach (DataGridViewRow rr in fields.Rows) { Template.Field m = (Template.Field)rr.Tag; if (m != null && (m.LeftAnchor?.Id == a.Id || m.TopAnchor?.Id == a.Id || m.RightAnchor?.Id == a.Id || m.BottomAnchor?.Id == a.Id)) { engaged = true; break; } } if (!engaged) { if (a.Id != t.ScalingAnchorId) { if (removeNotLinkedAnchors == null) { removeNotLinkedAnchors = Message.YesNo("The template contains not linked anchor[s]. Remove them?", this); } if (removeNotLinkedAnchors == true) { continue; } } } } } } t.Anchors.Add((Template.Anchor)Serialization.Json.Clone2(a)); } t.Anchors = t.Anchors.OrderBy(a => a.Id).ToList(); if (saving) { t.GetScalingAnchor();//check is it is correct; } t.Conditions = new List <Template.Condition>(); foreach (DataGridViewRow r in conditions.Rows) { Template.Condition c = (Template.Condition)r.Tag; if (c == null) { continue; } if (saving) { if (!c.IsSet()) { throw new Exception("Condition[name=" + c.Name + "] is not set!"); } BooleanEngine.Check(c.Value, t.Anchors.Select(x => x.Id)); } t.Conditions.Add((Template.Condition)Serialization.Json.Clone2(c)); } if (saving) { var dcs = t.Conditions.GroupBy(x => x.Name).Where(x => x.Count() > 1).FirstOrDefault(); if (dcs != null) { throw new Exception("Condition '" + dcs.First().Name + "' is duplicated!"); } } t.Fields = new List <Template.Field>(); foreach (DataGridViewRow r in fields.Rows) { Template.Field f = (Template.Field)r.Tag; if (f == null) { continue; } if (saving && !f.IsSet()) { throw new Exception("Field[" + r.Index + "] is not set!"); } if (saving) { foreach (int?ai in new List <int?> { f.LeftAnchor?.Id, f.TopAnchor?.Id, f.RightAnchor?.Id, f.BottomAnchor?.Id }) { if (ai != null && t.Anchors.FirstOrDefault(x => x.Id == ai) == null) { throw new Exception("Anchor[Id=" + ai + " does not exist."); } } } t.Fields.Add((Template.Field)Serialization.Json.Clone2(f)); } if (saving) { if (t.Fields.Count < 1) { throw new Exception("Fields is empty!"); } var fs = t.Fields.GroupBy(x => x.Name).Where(x => x.GroupBy(a => a.GetType()).Count() > 1).FirstOrDefault(); if (fs != null) { throw new Exception("Definitions of the field '" + fs.First().Name + "' are not of the same type!"); } } if (saving) { t.Editor = new Template.EditorSettings { //TestFile = testFile.Text, TestPictureScale = pictureScale.Value, ExtractFieldsAutomaticallyWhenPageChanged = ExtractFieldsAutomaticallyWhenPageChanged.Checked, ShowFieldTextLineSeparators = ShowFieldTextLineSeparators.Checked, CheckConditionsAutomaticallyWhenPageChanged = CheckConditionsAutomaticallyWhenPageChanged.Checked, }; } return(t); } }
Template getTemplateFromUI(bool saving) { Template t = new Template(); if (saving && string.IsNullOrWhiteSpace(name.Text)) { throw new Exception("Name is empty!"); } t.Name = name.Text.Trim(); t.TextAutoInsertSpace = new TextAutoInsertSpace { Threshold = (float)textAutoInsertSpaceThreshold.Value, Representative = textAutoInsertSpaceRepresentative.Text, }; t.PageRotation = (Template.PageRotations)pageRotation.SelectedIndex; t.AutoDeskew = autoDeskew.Checked; t.AutoDeskewThreshold = (int)autoDeskewThreshold.Value; bool?removeNotLinkedAnchors = null; t.Anchors = new List <Template.Anchor>(); List <int> conditionAnchorIds = null; if (saving) { conditionAnchorIds = new List <int>(); foreach (DataGridViewRow r in conditions.Rows) { Template.Condition c = (Template.Condition)r.Tag; if (c != null && c.IsSet()) { conditionAnchorIds.AddRange(BooleanEngine.GetAnchorIds(c.Value)); } } conditionAnchorIds = conditionAnchorIds.Distinct().ToList(); } foreach (DataGridViewRow r in anchors.Rows) { Template.Anchor a = (Template.Anchor)r.Tag; if (a == null) { continue; } if (saving) { if (!a.IsSet()) { throw new Exception("Anchor[Id=" + a.Id + "] is not set!"); } bool engaged = false; if (conditionAnchorIds.Contains(a.Id)) { engaged = true; } if (!engaged) { foreach (DataGridViewRow rr in anchors.Rows) { Template.Anchor a_ = (Template.Anchor)rr.Tag; if (a_ == null) { continue; } if (a_.ParentAnchorId == a.Id) { engaged = true; break; } } } if (!engaged) { foreach (DataGridViewRow rr in fields.Rows) { Template.Field m = (Template.Field)rr.Tag; if (m != null && (m.LeftAnchor?.Id == a.Id || m.TopAnchor?.Id == a.Id || m.RightAnchor?.Id == a.Id || m.BottomAnchor?.Id == a.Id)) { engaged = true; break; } } } if (!engaged) { if (removeNotLinkedAnchors == null) { removeNotLinkedAnchors = Message.YesNo("The template contains not linked anchor[s]. Should they be removed?"); } if (removeNotLinkedAnchors == true) { continue; } } } t.Anchors.Add(a); } t.Anchors = t.Anchors.OrderBy(a => a.Id).ToList(); t.Conditions = new List <Template.Condition>(); foreach (DataGridViewRow r in conditions.Rows) { Template.Condition c = (Template.Condition)r.Tag; if (c == null) { continue; } if (saving) { if (!c.IsSet()) { throw new Exception("Condition[name=" + c.Name + "] is not set!"); } BooleanEngine.Check(c.Value, t.Anchors.Select(x => x.Id)); } t.Conditions.Add(c); } if (saving) { var dcs = t.Conditions.GroupBy(x => x.Name).Where(x => x.Count() > 1).FirstOrDefault(); if (dcs != null) { throw new Exception("Condition '" + dcs.First().Name + "' is duplicated!"); } } t.Fields = new List <Template.Field>(); foreach (DataGridViewRow r in fields.Rows) { Template.Field f = (Template.Field)r.Tag; if (f == null) { continue; } if (saving && !f.IsSet()) { throw new Exception("Field[" + r.Index + "] is not set!"); } if (saving) { foreach (int?ai in new List <int?> { f.LeftAnchor?.Id, f.TopAnchor?.Id, f.RightAnchor?.Id, f.BottomAnchor?.Id }) { if (ai != null && t.Anchors.FirstOrDefault(x => x.Id == ai) == null) { throw new Exception("Anchor[Id=" + ai + " does not exist."); } } } t.Fields.Add(f); } if (saving) { if (t.Fields.Count < 1) { throw new Exception("Fields is empty!"); } //var dfs = t.Fields.GroupBy(x => x.Name).Where(x => x.Count() > 1).FirstOrDefault(); //if (dfs != null) // throw new Exception("Field '" + dfs.First().Name + "' is duplicated!"); //foreach (string columnOfTable in t.Fields.Where(x => x is Template.Field.PdfText).Select(x => (Template.Field.PdfText)x).Where(x => x.ColumnOfTable != null).Select(x => x.ColumnOfTable)) //{ // Dictionary<string, List<Template.Field>> fieldName2orderedFields = new Dictionary<string, List<Template.Field>>(); // foreach (Template.Field.PdfText pt in t.Fields.Where(x => x is Template.Field.PdfText).Select(x => (Template.Field.PdfText)x).Where(x => x.ColumnOfTable == columnOfTable)) // { // List<Template.Field> fs; // if (!fieldName2orderedFields.TryGetValue(pt.Name, out fs)) // { // fs = new List<Template.Field>(); // fieldName2orderedFields[pt.Name] = fs; // } // fs.Add(pt); // } // int definitionCount = fieldName2orderedFields.Max(x => x.Value.Count()); // foreach (string fn in fieldName2orderedFields.Keys) // if (definitionCount > fieldName2orderedFields[fn].Count) // throw new Exception("Field '" + fn + "' is column of table " + columnOfTable + " and so it must have the same number of definitions as the rest column fields!"); //} foreach (Template.Field f0 in t.Fields) { int tableDefinitionsCount = t.Fields.Where(x => x.Name == f0.Name).Count(); string fn = t.Fields.Where(x => x.ColumnOfTable == f0.Name).GroupBy(x => x.Name).Where(x => x.Count() > tableDefinitionsCount).FirstOrDefault()?.First().Name; if (fn != null) { throw new Exception("Field '" + fn + "' is a column of table field " + f0.Name + " so " + f0.Name + " must have number of definitions not less then that of " + fn + "."); } } } if (saving) { t.Editor = new Template.EditorSettings { TestFile = testFile.Text, TestPictureScale = pictureScale.Value, ExtractFieldsAutomaticallyWhenPageChanged = ExtractFieldsAutomaticallyWhenPageChanged.Checked, CheckConditionsAutomaticallyWhenPageChanged = CheckConditionsAutomaticallyWhenPageChanged.Checked, }; } return(t); }
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); } }