diff --git a/mallinkOcr/pom.xml b/mallinkOcr/pom.xml new file mode 100644 index 000000000..b43f32111 --- /dev/null +++ b/mallinkOcr/pom.xml @@ -0,0 +1,34 @@ + + + + mallink + com.iformall + 1.0 + + 4.0.0 + + mallinkOcr + + + + net.java.dev.jna + jna + 4.1.0 + + + net.sourceforge.tess4j + tess4j + 3.4.0 + + + com.sun.jna + jna + + + + + + + \ No newline at end of file diff --git a/mallinkOcr/src/main/java/com/iformall/ocr/FormallTess4j.java b/mallinkOcr/src/main/java/com/iformall/ocr/FormallTess4j.java new file mode 100644 index 000000000..68ee0cd27 --- /dev/null +++ b/mallinkOcr/src/main/java/com/iformall/ocr/FormallTess4j.java @@ -0,0 +1,281 @@ +package com.iformall.ocr; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; + +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.recognition.software.jdeskew.ImageDeskew; +import net.sourceforge.tess4j.ITessAPI.TessPageIteratorLevel; +import net.sourceforge.tess4j.ITesseract; +import net.sourceforge.tess4j.ITesseract.RenderedFormat; +import net.sourceforge.tess4j.Tesseract; +import net.sourceforge.tess4j.Word; +import net.sourceforge.tess4j.util.ImageHelper; +import net.sourceforge.tess4j.util.LoggHelper; +import net.sourceforge.tess4j.util.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * https://www.cnblogs.com/pejsidney/p/9487881.html + * Tess4J是对Tesseract OCR API.的Java JNA 封装。使java能够通过调用Tess4J的API来使用Tesseract OCR。支持的格式:TIFF,JPEG,GIF,PNG,BMP,JPEG,and PDF + Tesseract 的github地址:https://github.com/tesseract-ocr/tesseract + Tess4J的github地址:https://github.com/nguyenq/tess4j + + Tess4J API 提供的功能: + 1、直接识别支持的文件 + 2、识别图片流 + 3、识别图片的某块区域 + 4、将识别结果保存为 TEXT/ HOCR/ PDF/ UNLV/ BOX + 5、通过设置取词的等级,提取识别出来的文字 + 6、获得每一个识别区域的具体坐标范围 + 7、调整倾斜的图片 + 8、裁剪图片 + 9、调整图片分辨率 + 10、从粘贴板获得图像 + 11、克隆一个图像(目的:创建一份一模一样的图片,与原图在操作修改上,不相 互影响) + 12、图片转换为二进制、黑白图像、灰度图像 + 13、反转图片颜色 + * @author alascor + */ +public class FormallTess4j { + + + private static final Logger logger = LoggerFactory.getLogger(new LoggHelper().toString()); + static final double MINIMUM_DESKEW_THRESHOLD = 0.05d; + + private static final String datapath = "src/main/resources"; + private static final String testResourcesLanguagePath = datapath+"/tessdata"; + private static final String tempfile = "/ocrtempfile/"; + + private static ITesseract instance = new Tesseract(); + + static { + instance.setDatapath(new File(datapath).getPath()); + } + + private static File urlImgToFile(String fileUrl) { + InputStream ins = null; + OutputStream os = null; + try { + URL url = new URL(fileUrl); + URLConnection c = url.openConnection(); + ins = c.getInputStream(); + File folder = new File (tempfile) ; + if (!folder.exists()) { + folder.mkdirs(); + } + File f = new File(tempfile+System.currentTimeMillis()+"-"+IdWorker.get32UUID()+".jpg"); + if (f.exists()) { + f.delete(); + } + f.createNewFile(); + os = new FileOutputStream(f); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + return f; + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }finally { + if (null != os) { + try { + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (null != ins) { + try { + ins.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return null; + } + + + public static String ocrLocalImgFile(String filePath) throws Exception { + File imageFile = new File(filePath); + return testDoOCR_File(imageFile); + } + + public static String ocrNetImgFile(String fileUrl) throws Exception { + File imageFile = urlImgToFile(fileUrl); + return testDoOCR_File(imageFile); + } + + /** + * Test of doOCR method, of class Tesseract. + * 根据图片文件进行识别 + * @throws Exception while processing image. + */ + private static String testDoOCR_File(File imageFile) throws Exception { + logger.info("doOCR on a jpg image"); + //set language + instance.setDatapath(testResourcesLanguagePath); + instance.setLanguage("chi_sim"); + String result = instance.doOCR(imageFile); + return result; + } + + + public static void main(String[] args) { + try { + System.out.println(ocrNetImgFile("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.my0832.com%2Fattachments%2Fbbs%2F20140424%2F201442413083356803_740_1186.jpg&refer=http%3A%2F%2Fimg.my0832.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1613903848&t=985fc4c6c7b7ee82cb98f97ab5bf1459")); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + +// +// /** +// * Test of doOCR method, of class Tesseract. +// * 根据图片流进行识别 +// * @throws Exception while processing image. +// */ +// public void testDoOCR_BufferedImage() throws Exception { +// logger.info("doOCR on a buffered image of a PNG"); +// File imageFile = new File(this.testResourcesDataPath, "ocr.png"); +// BufferedImage bi = ImageIO.read(imageFile); +// +// //set language +// instance.setDatapath(testResourcesLanguagePath); +// instance.setLanguage("chi_sim"); +// +// String result = instance.doOCR(bi); +// logger.info(result); +// } +// +// /** +// * Test of getSegmentedRegions method, of class Tesseract. +// * 得到每一个划分区域的具体坐标 +// * @throws java.lang.Exception +// */ +// public void testGetSegmentedRegions() throws Exception { +// logger.info("getSegmentedRegions at given TessPageIteratorLevel"); +// File imageFile = new File(testResourcesDataPath, "ocr.png"); +// BufferedImage bi = ImageIO.read(imageFile); +// int level = TessPageIteratorLevel.RIL_SYMBOL; +// logger.info("PageIteratorLevel: " + Utils.getConstantName(level, TessPageIteratorLevel.class)); +// List result = instance.getSegmentedRegions(bi, level); +// for (int i = 0; i < result.size(); i++) { +// Rectangle rect = result.get(i); +// logger.info(String.format("Box[%d]: x=%d, y=%d, w=%d, h=%d", i, rect.x, rect.y, rect.width, rect.height)); +// } +// +// assertTrue(result.size() > 0); +// } +// +// +// /** +// * Test of doOCR method, of class Tesseract. +// * 根据定义坐标范围进行识别 +// * @throws Exception while processing image. +// */ +// public void testDoOCR_File_Rectangle() throws Exception { +// logger.info("doOCR on a BMP image with bounding rectangle"); +// File imageFile = new File(this.testResourcesDataPath, "ocr.png"); +// //设置语言库 +// instance.setDatapath(testResourcesLanguagePath); +// instance.setLanguage("chi_sim"); +// //划定区域 +// // x,y是以左上角为原点,width和height是以xy为基础 +// Rectangle rect = new Rectangle(84, 21, 15, 13); +// String result = instance.doOCR(imageFile, rect); +// logger.info(result); +// } +// +// /** +// * Test of createDocuments method, of class Tesseract. +// * 存储结果 +// * @throws java.lang.Exception +// */ +// public void testCreateDocuments() throws Exception { +// logger.info("createDocuments for png"); +// File imageFile = new File(this.testResourcesDataPath, "ocr.png"); +// String outputbase = "target/test-classes/docrenderer-2"; +// List formats = new ArrayList(Arrays.asList(RenderedFormat.HOCR, RenderedFormat.TEXT)); +// +// //设置语言库 +// instance.setDatapath(testResourcesLanguagePath); +// instance.setLanguage("chi_sim"); +// +// instance.createDocuments(new String[]{imageFile.getPath()}, new String[]{outputbase}, formats); +// } +// +// /** +// * Test of getWords method, of class Tesseract. +// * 取词方法 +// * @throws java.lang.Exception +// */ +// public void testGetWords() throws Exception { +// logger.info("getWords"); +// File imageFile = new File(this.testResourcesDataPath, "ocr.png"); +// +// //设置语言库 +// instance.setDatapath(testResourcesLanguagePath); +// instance.setLanguage("chi_sim"); +// +// //按照每个字取词 +// int pageIteratorLevel = TessPageIteratorLevel.RIL_SYMBOL; +// logger.info("PageIteratorLevel: " + Utils.getConstantName(pageIteratorLevel, TessPageIteratorLevel.class)); +// BufferedImage bi = ImageIO.read(imageFile); +// List result = instance.getWords(bi, pageIteratorLevel); +// +// //print the complete result +// for (Word word : result) { +// logger.info(word.toString()); +// } +// } +// +// /** +// * Test of Invalid memory access. +// * 处理倾斜 +// * @throws Exception while processing image. +// */ +// public void testDoOCR_SkewedImage() throws Exception { +// //设置语言库 +// instance.setDatapath(testResourcesLanguagePath); +// instance.setLanguage("chi_sim"); +// +// logger.info("doOCR on a skewed PNG image"); +// File imageFile = new File(this.testResourcesDataPath, "ocr_skewed.jpg"); +// BufferedImage bi = ImageIO.read(imageFile); +// ImageDeskew id = new ImageDeskew(bi); +// double imageSkewAngle = id.getSkewAngle(); // determine skew angle +// if ((imageSkewAngle > MINIMUM_DESKEW_THRESHOLD || imageSkewAngle < -(MINIMUM_DESKEW_THRESHOLD))) { +// bi = ImageHelper.rotateImage(bi, -imageSkewAngle); // deskew image +// } +// +// String result = instance.doOCR(bi); +// logger.info(result); +// } + +} diff --git a/mallinkOcr/src/main/resources/Read.txt b/mallinkOcr/src/main/resources/Read.txt new file mode 100644 index 000000000..f10a0bd35 --- /dev/null +++ b/mallinkOcr/src/main/resources/Read.txt @@ -0,0 +1,3 @@ +https://www.cnblogs.com/wj-1314/p/9454656.html + +https://www.cnblogs.com/pejsidney/p/9487881.html \ No newline at end of file diff --git a/mallinkOcr/src/main/resources/tessdata/chi_sim.traineddata b/mallinkOcr/src/main/resources/tessdata/chi_sim.traineddata new file mode 100644 index 000000000..eeb66cfbd Binary files /dev/null and b/mallinkOcr/src/main/resources/tessdata/chi_sim.traineddata differ diff --git a/mallinkOcr/src/main/resources/tessdata/eng.traineddata b/mallinkOcr/src/main/resources/tessdata/eng.traineddata new file mode 100644 index 000000000..f4744c201 Binary files /dev/null and b/mallinkOcr/src/main/resources/tessdata/eng.traineddata differ diff --git a/mallinkOcr/src/main/resources/tessdata/osd.traineddata b/mallinkOcr/src/main/resources/tessdata/osd.traineddata new file mode 100644 index 000000000..183644aa5 Binary files /dev/null and b/mallinkOcr/src/main/resources/tessdata/osd.traineddata differ diff --git a/mallinkOcr/src/main/resources/tessdata/pdf.ttf b/mallinkOcr/src/main/resources/tessdata/pdf.ttf new file mode 100644 index 000000000..c33bafe3b --- /dev/null +++ b/mallinkOcr/src/main/resources/tessdata/pdf.ttf @@ -0,0 +1 @@ +tessconfigs/pdf.ttf \ No newline at end of file diff --git a/mallinkService/pom.xml b/mallinkService/pom.xml index 29d293544..c9a09ec90 100644 --- a/mallinkService/pom.xml +++ b/mallinkService/pom.xml @@ -34,7 +34,14 @@ com.iformall mybatis-multi-tenancy 1.0 - + + + + + com.iformall + mallinkOcr + 1.0 + diff --git a/pom.xml b/pom.xml index 8318e1289..e26b008e2 100644 --- a/pom.xml +++ b/pom.xml @@ -11,6 +11,7 @@ 1.0 + mallinkOcr mybatis-multi-tenancy mallinkService mallinkCallback @@ -22,7 +23,7 @@ mallinkSchedule mallinkMQConsumer mallinkWebSocketServer - mallinkPublicApi + mallinkPublicApi