!752 static BWImage img; static ImageSurface is2; static float threshold = 0.99f; // for horizontalAutoSplit static JTable table; static JTextField tfText; static L split; static L characters; concepts. concept Result { BWImage inputImage; float horizontalSplitThreshold; L characters; //Bool splitOK; S text; } p { concepts(); dbBot(); if (img == null) img = getBWImageFromClipboard(); if (img == null) img = loadBWImage("#1005702"); update(); } svoid update() { RGBImage vis = visualize().toRGB(); if (is2 == null) { is2 = showZoomedImage(vis); addToWindowAndPack(is2, liveSliderZeroToOne(threshold/10000f*9999f, voidfunc(float x) { threshold = x*10000f/9999f; update(); })); } else is2.setImage(vis); // show table new L data; characters = new L; for (Rect r : split) { BWImage clip = img.clip(r); characters.add(clip); data.add(ll(clip.getBufferedImage(), md5OfBWImage(clip))); } bool first = table == null; table = showTableWithImages("Characters + MD5", splitAtSpace("Character MD5"), data, table); if (first) { table.setRowHeight(25); addToWindow(table, centerAndEast( withLabel("Text:", tfText = new JTextField), jbutton("Save result", "saveResult"))); onEnter(tfText, "saveResult"); } } svoid saveResult { S text = tfText.getText(); /*if (l(text) != l(characters)) messageBox("Character count doesn't match! " + l(text) + " vs " + l(characters)); else*/ { Result result = cnew(Result, inputImage := img, horizontalSplitThreshold := threshold, +characters, +text); messageBox("Result saved! id: " + result.id); } } static BWImage visualize() { BWImage im = new BWImage(img); for (Rect r : split = horizontalAutoSplit(img, threshold)) { r = autoCropOfBWImage(img, r); darkenBWImagePart(im, r); } ret im; }