!7 concept TestImage { new Ref pngFile; S imageMD5; int width, height; bool textKnown; S text; } p-subst { SimpleCRUD crud = new SimpleCRUD(TestImage) { @Override JComponent fieldComponent(TestImage c, S field) { if (eq(field, "pngFile")) ret new ImageChooser((PNGFile) cget(c, "pngFile")); ret super.fieldComponent(c, field); } @Override void makeComponents(TestImage c, Map map) { for (S field : listMinus((L) conceptFieldsInOrder(cc), "width", "height", "imageMD5")) map.put(field, fieldComponent(c, field)); } @Override void saveData(TestImage c, Map components) { super.saveData(c, components); fixEntry(c); } }; /*final L fields = concatLists(ll("id"), conceptFieldsInOrder(c)); crud.renderer = func(TestImage c) { Map map = litorderedmap(); for (S field : fields) map.put(field, renderForTable(cget(cc, field))); ret map; };*/ crud.show("OCR Test Images"); bot("OCR Test Images."); hideConsole(); } answer { if "add image * with unknown text" { PNGFile pngFile = new PNGFile(unstructureBufferedImage($1)); if (hasConcept(TestImage, imageMD5 := pngFile.md5())) ret "Entry already exists"; long id = fixEntry(cnew(TestImage, +pngFile)).id; ret "OK, ID of new entry: " + id; } } static TestImage fixEntry(TestImage c) { BufferedImage img = c.pngFile.has() ? c.pngFile->getImage() : null; if (img == null) cset(c, imageMD5 := null, width := 0, height := 0); else cset(c, imageMD5 := md5OfBufferedImage(img), width := img.getWidth(), height := img.getHeight()); ret c; }