| @@ -32,6 +32,9 @@ public class CApplication { | |||||
| @Value("${fm.upload_dir}") | @Value("${fm.upload_dir}") | ||||
| private String uploadDir; | private String uploadDir; | ||||
| @Value("${fm.ocr_data}") | |||||
| private String ocrData; | |||||
| @Bean | @Bean | ||||
| public boolean isFmException() { | public boolean isFmException() { | ||||
| @@ -3,6 +3,7 @@ package com.iformall.controller; | |||||
| import com.iformall.common.ErrorCode; | import com.iformall.common.ErrorCode; | ||||
| import com.iformall.common.ResultData; | import com.iformall.common.ResultData; | ||||
| import com.iformall.domain.po.WxMerchantOcrModel; | import com.iformall.domain.po.WxMerchantOcrModel; | ||||
| import com.iformall.domain.po.WxOcrModel; | |||||
| import com.iformall.domain.po.base.TenantEntity; | import com.iformall.domain.po.base.TenantEntity; | ||||
| import com.iformall.ocr.FormallTess4j; | import com.iformall.ocr.FormallTess4j; | ||||
| import com.iformall.service.WxOcrService; | import com.iformall.service.WxOcrService; | ||||
| @@ -28,7 +29,8 @@ public class WxOcrController extends BaseController { | |||||
| @Autowired | @Autowired | ||||
| private WxOcrService ocrService; | private WxOcrService ocrService; | ||||
| @Autowired | |||||
| private String ocrData; | |||||
| @ApiOperation("分析图片信息") | @ApiOperation("分析图片信息") | ||||
| @GetMapping("/analyImage") | @GetMapping("/analyImage") | ||||
| @@ -38,13 +40,17 @@ public class WxOcrController extends BaseController { | |||||
| }) | }) | ||||
| public ResultData analyImage(Long merchantId,String imageUrl) { | public ResultData analyImage(Long merchantId,String imageUrl) { | ||||
| TenantEntity tenantEntity = getTenantInfo(); | TenantEntity tenantEntity = getTenantInfo(); | ||||
| WxMerchantOcrModel model = ocrService.getMerchantOcrModel(merchantId, tenantEntity.getTenantId(), tenantEntity.getParentTenantId()); | |||||
| if (null == model) { | |||||
| WxMerchantOcrModel MerchantModel = ocrService.getMerchantOcrModel(merchantId, tenantEntity.getTenantId(), tenantEntity.getParentTenantId()); | |||||
| if (null == MerchantModel) { | |||||
| return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(), "当前商户没有配置OCR模板"); | return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(), "当前商户没有配置OCR模板"); | ||||
| } | } | ||||
| WxOcrModel ocrModel = ocrService.getOcrModelById(MerchantModel.getOcrModelId()); | |||||
| if (null == ocrModel) { | |||||
| return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(), "当前商户配置的OCR模板未查询到"); | |||||
| } | |||||
| String result; | String result; | ||||
| try { | try { | ||||
| result = FormallTess4j.ocrNetImgFile(imageUrl); | |||||
| result = FormallTess4j.ocrNetImgFile(ocrData,imageUrl,ocrModel.getFontName()); | |||||
| return new ResultData(result); | return new ResultData(result); | ||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| logger.error("ocr识别失败。",e); | logger.error("ocr识别失败。",e); | ||||
| @@ -160,6 +160,7 @@ fm: | |||||
| deploy: 1 | deploy: 1 | ||||
| open: true | open: true | ||||
| upload_dir: /home/test/server/uploads/ | upload_dir: /home/test/server/uploads/ | ||||
| ocr_data: /home/test/server/ocr_data/ | |||||
| logging: | logging: | ||||
| level: | level: | ||||
| @@ -115,6 +115,7 @@ fm: | |||||
| deploy: 3 | deploy: 3 | ||||
| open: true | open: true | ||||
| upload_dir: /root/uploads/ | upload_dir: /root/uploads/ | ||||
| ocr_data: /root/ocr_data/ | |||||
| logging: | logging: | ||||
| level: | level: | ||||
| @@ -93,6 +93,7 @@ fm: | |||||
| deploy: 2 | deploy: 2 | ||||
| open: true | open: true | ||||
| upload_dir: /home/ec2-user/server/uploads/ | upload_dir: /home/ec2-user/server/uploads/ | ||||
| ocr_data: /home/ec2-user/server/ocr_data/ | |||||
| logging: | logging: | ||||
| level: | level: | ||||
| @@ -119,14 +119,14 @@ public class FormallTess4j { | |||||
| } | } | ||||
| public static String ocrLocalImgFile(String filePath) throws Exception { | |||||
| File imageFile = new File(filePath); | |||||
| return testDoOCR_File(imageFile); | |||||
| private static String ocrLocalImgFile(String languagePath,String filePath,String fontName) throws Exception { | |||||
| File imageFile = new File(filePath,fontName); | |||||
| return testDoOCR_File(languagePath,imageFile,fontName); | |||||
| } | } | ||||
| public static String ocrNetImgFile(String fileUrl) throws Exception { | |||||
| public static String ocrNetImgFile(String languagePath,String fileUrl,String fontName) throws Exception { | |||||
| File imageFile = urlImgToFile(fileUrl); | File imageFile = urlImgToFile(fileUrl); | ||||
| return testDoOCR_File(imageFile); | |||||
| return testDoOCR_File(languagePath,imageFile,fontName); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -134,11 +134,11 @@ public class FormallTess4j { | |||||
| * 根据图片文件进行识别 | * 根据图片文件进行识别 | ||||
| * @throws Exception while processing image. | * @throws Exception while processing image. | ||||
| */ | */ | ||||
| private static String testDoOCR_File(File imageFile) throws Exception { | |||||
| public static String testDoOCR_File(String languagePath,File imageFile,String fontName) throws Exception { | |||||
| logger.info("doOCR on a jpg image"); | logger.info("doOCR on a jpg image"); | ||||
| //set language | //set language | ||||
| instance.setDatapath(testResourcesLanguagePath); | |||||
| instance.setLanguage("test1"); | |||||
| instance.setDatapath(languagePath); | |||||
| instance.setLanguage(fontName); | |||||
| String result = instance.doOCR(imageFile); | String result = instance.doOCR(imageFile); | ||||
| return result; | return result; | ||||
| } | } | ||||
| @@ -146,14 +146,13 @@ public class FormallTess4j { | |||||
| public static void main(String[] args) { | public static void main(String[] args) { | ||||
| try { | 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")); | |||||
| System.out.println(ocrNetImgFile(testResourcesLanguagePath,"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","test1")); | |||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| // TODO Auto-generated catch block | // TODO Auto-generated catch block | ||||
| e.printStackTrace(); | e.printStackTrace(); | ||||
| } | } | ||||
| } | } | ||||
| // | // | ||||
| // /** | // /** | ||||
| // * Test of doOCR method, of class Tesseract. | // * Test of doOCR method, of class Tesseract. | ||||
| @@ -15,90 +15,38 @@ public class FormallTess4jTrain { | |||||
| private static final String newFileFolder = "C:\\Users\\iformall\\Desktop\\newfile"; | private static final String newFileFolder = "C:\\Users\\iformall\\Desktop\\newfile"; | ||||
| /** | |||||
| * 第一步,用jTessBoxEditor --> Tools --> Merge 多选图片,保存为tif格式 | |||||
| * 命名: [lang].[fontname].exp[num].tif lang是语言 fontname是字体 | |||||
| */ | |||||
| private static final String huanhangstr = " \n"; | |||||
| /** | |||||
| * 第二部,用tif生成box | |||||
| * @param args | |||||
| */ | |||||
| public static void createBoxFile(String tifFileName,String lang,String fontName) { | |||||
| private static String getprefix(String lang,String fontName) { | |||||
| String realFileName = lang+"."+fontName+".exp0"; | |||||
| return realFileName; | |||||
| } | |||||
| private static String createBoxFile(String tifFileName,String lang,String fontName) { | |||||
| String prefix = getprefix(lang,fontName); | String prefix = getprefix(lang,fontName); | ||||
| String realFileName = prefix+".tif"; | String realFileName = prefix+".tif"; | ||||
| if (tifFileName.equals(realFileName)) { | if (tifFileName.equals(realFileName)) { | ||||
| String cmdstr = "tesseract "+tifFileName+" "+prefix+" -l chi_sim batch.nochop makebox"; | String cmdstr = "tesseract "+tifFileName+" "+prefix+" -l chi_sim batch.nochop makebox"; | ||||
| System.out.println(cmdstr); | |||||
| return cmdstr; | |||||
| //String result = executeLocalCmd(cmdstr, null); | //String result = executeLocalCmd(cmdstr, null); | ||||
| //System.out.println("Done createBoxFile"+result); | //System.out.println("Done createBoxFile"+result); | ||||
| }else { | |||||
| return "文件必须是.tif"; | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * 第三步,用jTessBoxEditor 打开.box文件进行矫正。 | |||||
| */ | |||||
| /** | |||||
| * 第四步,新建font_properties,内容 [fontName] 0 0 0 0 0 | |||||
| * <italic> 、<bold> 、<fixed> 、<serif>、 <fraktur>的取值为1或0,表示字体是否具有这些属性 | |||||
| */ | |||||
| public static void createFontPorperties(String fontName,int italic, int bold, int fixed,int serif,int fraktur) { | |||||
| try { | |||||
| String content = fontName+" "+italic+" "+bold+" "+fixed+" "+serif+" "+fraktur; | |||||
| System.out.println(content); | |||||
| File file = new File(newFileFolder+"\\font_properties"); | |||||
| if (file.exists()) { | |||||
| file.delete(); | |||||
| } | |||||
| file.createNewFile(); | |||||
| FileWriter fw = new FileWriter(file.getAbsoluteFile()); | |||||
| BufferedWriter bw = new BufferedWriter(fw); | |||||
| bw.write(content); | |||||
| bw.close(); | |||||
| System.out.println("Done createFontPorperties"); | |||||
| } catch (IOException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| } | |||||
| /*** | |||||
| * 第五步:执行以下命令 | |||||
| * @param lang | |||||
| * @param fontName | |||||
| * @return | |||||
| */ | |||||
| public static void createTrainFiles(String lang,String fontName) { | |||||
| private static String createTranFile(String lang,String fontName) { | |||||
| String prefix = getprefix(lang,fontName); | String prefix = getprefix(lang,fontName); | ||||
| String realFileName = prefix+".tif"; | String realFileName = prefix+".tif"; | ||||
| String trainCmdstr = "tesseract "+realFileName+" "+prefix+" nobatch box.train"; | String trainCmdstr = "tesseract "+realFileName+" "+prefix+" nobatch box.train"; | ||||
| System.out.println(trainCmdstr); | |||||
| //executeLocalCmd(trainCmdstr, null); | |||||
| //此处可以批量开始 | |||||
| return trainCmdstr; | |||||
| } | |||||
| private static String getBoxFont(String lang,String fontName) { | |||||
| String prefix = getprefix(lang,fontName); | |||||
| String extractorCmdstr = "unicharset_extractor "+prefix+".box"; | String extractorCmdstr = "unicharset_extractor "+prefix+".box"; | ||||
| System.out.println(extractorCmdstr); | |||||
| //executeLocalCmd(extractorCmdstr, null); | |||||
| String shapeCmdStr = "shapeclustering -F font_properties -U unicharset "+prefix+".tr"; | |||||
| System.out.println(shapeCmdStr); | |||||
| //executeLocalCmd(shapeCmdStr, null); | |||||
| String mftraingCmdstr = "mftraining -F font_properties -U unicharset -O unicharset "+prefix+".tr"; | |||||
| System.out.println(mftraingCmdstr); | |||||
| //executeLocalCmd(mftraingCmdstr, null); | |||||
| String cntrainCmdstr = "cntraining "+prefix+".tr"; | |||||
| System.out.println(cntrainCmdstr); | |||||
| //executeLocalCmd(cntrainCmdstr, null); | |||||
| //批量结束 | |||||
| //System.out.println("DONE createTrainFiles !"); | |||||
| return extractorCmdstr; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -108,28 +56,23 @@ public class FormallTess4jTrain { | |||||
| * @param fontName | * @param fontName | ||||
| * @return | * @return | ||||
| */ | */ | ||||
| public static void renameTrainFiles(String fontName) { | |||||
| private static String renameTrainFiles(String fontName) { | |||||
| StringBuffer sb = new StringBuffer(); | |||||
| String renCmdstr = "REN unicharset "+fontName+".unicharset"; | String renCmdstr = "REN unicharset "+fontName+".unicharset"; | ||||
| System.out.println(renCmdstr); | |||||
| //executeLocalCmd(renCmdstr, null); | |||||
| sb.append(renCmdstr).append(huanhangstr); | |||||
| renCmdstr = "REN inttemp "+fontName+".inttemp"; | renCmdstr = "REN inttemp "+fontName+".inttemp"; | ||||
| System.out.println(renCmdstr); | |||||
| //executeLocalCmd(renCmdstr, null); | |||||
| sb.append(renCmdstr).append(huanhangstr); | |||||
| renCmdstr = "REN pffmtable "+fontName+".pffmtable"; | renCmdstr = "REN pffmtable "+fontName+".pffmtable"; | ||||
| System.out.println(renCmdstr); | |||||
| //executeLocalCmd(renCmdstr, null); | |||||
| sb.append(renCmdstr).append(huanhangstr); | |||||
| renCmdstr = "REN shapetable "+fontName+".shapetable"; | renCmdstr = "REN shapetable "+fontName+".shapetable"; | ||||
| System.out.println(renCmdstr); | |||||
| //executeLocalCmd(renCmdstr, null); | |||||
| sb.append(renCmdstr).append(huanhangstr); | |||||
| renCmdstr = "REN normproto "+fontName+".normproto"; | renCmdstr = "REN normproto "+fontName+".normproto"; | ||||
| System.out.println(renCmdstr); | |||||
| //executeLocalCmd(renCmdstr, null); | |||||
| //System.out.println("DONE renameTrainFiles !"); | |||||
| sb.append(renCmdstr).append(huanhangstr); | |||||
| return sb.toString(); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -138,87 +81,54 @@ public class FormallTess4jTrain { | |||||
| * @param fontName | * @param fontName | ||||
| * @return | * @return | ||||
| */ | */ | ||||
| public static void mergeTrainFiles(String fontName) { | |||||
| private static String mergeTrainFiles(String fontName) { | |||||
| String mergeCmdstr = "combine_tessdata "+fontName+"."; | String mergeCmdstr = "combine_tessdata "+fontName+"."; | ||||
| System.out.println(mergeCmdstr); | |||||
| //executeLocalCmd(mergeCmdstr, null); | |||||
| //System.out.println("DONE mergeTrainFiles !"); | |||||
| } | |||||
| private static String getprefix(String lang,String fontName) { | |||||
| String realFileName = lang+"."+fontName+".exp0"; | |||||
| return realFileName; | |||||
| return mergeCmdstr; | |||||
| } | } | ||||
| private static String executeLocalCmd(String cmd, File workpath) { | |||||
| try { | |||||
| String[] cmdA = { "cmd.exe", "/c", cmd }; | |||||
| Process process = null; | |||||
| if(workpath==null){ | |||||
| process = Runtime.getRuntime().exec(cmdA); | |||||
| }else{ | |||||
| process = Runtime.getRuntime().exec(cmdA, null, workpath); | |||||
| } | |||||
| // LineNumberReader br = new LineNumberReader(new InputStreamReader(process.getInputStream())); | |||||
| LineNumberReader br = new LineNumberReader(new InputStreamReader(process.getInputStream(),"GBK")); | |||||
| StringBuffer sb = new StringBuffer(); | |||||
| String line; | |||||
| while ((line = br.readLine()) != null) { | |||||
| sb.append(line).append("\n"); | |||||
| } | |||||
| return sb.toString(); | |||||
| } catch (Exception e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return null; | |||||
| } | |||||
| public static void main(String[] args) { | |||||
| // String cmdStr = "mspaint";// 打开画板 | |||||
| // //cmdStr = "ren C:/server/data/ccgavr/3.png C:/server/data/ccgavr/4.png";// 重命名,DOS中不可 | |||||
| // //cmdStr = "ren 3.png 4.png"; | |||||
| // cmdStr = "ipconfig"; | |||||
| //// executeCMD(cmdStr); | |||||
| // System.out.println(executeLocalCmd(cmdStr, null)); | |||||
| /**第一步,用jTessBoxEditor --> Tools --> Merge 多选图片,保存为tif格式*/ | |||||
| System.out.println("第一步,用jTessBoxEditor --> Tools --> Merge 多选图片,保存为tif格式 . 命名格式:lang.fontName.exp0.tif"); | |||||
| System.out.println("》》》》》》》》》"); | |||||
| /**第二部,用tif生成box*/ | |||||
| System.out.println("第二步,用tif生成box"); | |||||
| createBoxFile("mylang.test1.exp0.tif", "mylang", "test1"); | |||||
| System.out.println("》》》》》》》》》"); | |||||
| /**第三步,用jTessBoxEditor 打开.box文件进行矫正。*/ | |||||
| System.out.println("第三步,用jTessBoxEditor 打开.box文件进行矫"); | |||||
| System.out.println("》》》》》》》》》"); | |||||
| /**第四步,新建font_properties,内容 [fontName] 0 0 0 0 0*/ | |||||
| System.out.println("第四步:新建font_properties,内容 [fontName] 0 0 0 0 0"); | |||||
| createFontPorperties("test1", 0, 0, 0, 0, 0); | |||||
| System.out.println("》》》》》》》》》"); | |||||
| /** 第五步:执行以下命令*/ | |||||
| System.out.println("第五步:执行以下命令"); | |||||
| createTrainFiles("mylang", "test1"); | |||||
| System.out.println("》》》》》》》》》"); | |||||
| /**第六步,执行完成后生成以下几个文件加前缀*/ | |||||
| System.out.println("第六步,执行完成后生成以下几个文件加前缀"); | |||||
| renameTrainFiles("test1"); | |||||
| System.out.println("》》》》》》》》》"); | |||||
| /**第七步:合并5个文件*/ | |||||
| System.out.println("第七步:合并5个文件"); | |||||
| mergeTrainFiles("test1"); | |||||
| public static String getTrainSteps(String lang,String fontName) { | |||||
| StringBuffer sb = new StringBuffer("请进入到样本图片文件夹用doc命令执行.").append(huanhangstr); | |||||
| sb.append("第一步,用jTessBoxEditor --> Tools --> Merge 多选图片,保存为tif格式 .命名格式为[lang].[fontName].exp0.tif. 命名:").append(lang).append(".").append(fontName).append(".exp0.tif ").append(huanhangstr); | |||||
| sb.append("............ ").append(huanhangstr); | |||||
| sb.append("第二步,用tif生成box ").append(huanhangstr); | |||||
| sb.append(createBoxFile(lang+"."+fontName+".exp0.tif", lang, fontName)).append(huanhangstr); | |||||
| sb.append("............ ").append(huanhangstr); | |||||
| sb.append("第三步,用jTessBoxEditor 打开.box文件进行矫正 ").append(huanhangstr); | |||||
| sb.append("............ ").append(huanhangstr); | |||||
| sb.append("第四步:用box文件生成。tr文件 ").append(huanhangstr); | |||||
| sb.append(createTranFile(lang,fontName)).append(huanhangstr); | |||||
| sb.append("............ ").append(huanhangstr); | |||||
| sb.append("第五步:提取box字符 ").append(huanhangstr); | |||||
| sb.append(getBoxFont(lang,fontName)).append(huanhangstr); | |||||
| sb.append("............ ").append(huanhangstr); | |||||
| sb.append("@@@!!!!从此处开始,可以处理多个字库处理。如原来的字库现在做升级,需要把老的字库的。tif,.box,.tr文件重新命名也放到同目录文件夹, ").append(huanhangstr); | |||||
| sb.append("............ ").append(huanhangstr); | |||||
| sb.append("第六步:新建font_properties(没有.txt后缀), 把所有box对应的字体特征加进去。").append(huanhangstr); | |||||
| sb.append("fontname为字体名称,保持和 图片集文件 .tif 和.box文件的前缀名一致 .<italic> 、<bold> 、<fixed> 、<serif>、 <fraktur>的取值为1或0,表示字体是否具有这些属性。 ").append(huanhangstr); | |||||
| sb.append("如以下内容: ").append(huanhangstr); | |||||
| sb.append("fontName1 0 0 0 0 0 ").append(huanhangstr); | |||||
| sb.append("fontName2 0 1 0 0 0 ").append(huanhangstr); | |||||
| sb.append("fontName3 1 1 0 0 0 ").append(huanhangstr); | |||||
| sb.append("............ ").append(huanhangstr); | |||||
| sb.append("第六步:批量执行系列命令。多个文件在后面累加。 ").append(huanhangstr); | |||||
| String prefix = getprefix(lang,fontName); | |||||
| String shapeCmdStr = "shapeclustering -F font_properties -U unicharset "+prefix+".tr [other .tr files...] "; | |||||
| sb.append(shapeCmdStr).append(huanhangstr); | |||||
| String mftraingCmdstr = "mftraining -F font_properties -U unicharset -O unicharset "+prefix+".tr [other .tr files...] "; | |||||
| sb.append(mftraingCmdstr).append(huanhangstr); | |||||
| String cntrainCmdstr = "cntraining "+prefix+".tr [other .tr files...] "; | |||||
| sb.append(cntrainCmdstr).append(huanhangstr); | |||||
| sb.append("............ ").append(huanhangstr); | |||||
| sb.append("第七步,执行完成后生成以下几个文件加前缀: unicharset、inttemp、pffmtable、shapetable、normproto 添加这几个文件的前缀为[fontName] ").append(huanhangstr); | |||||
| sb.append(renameTrainFiles(fontName)); | |||||
| sb.append("............ ").append(huanhangstr); | |||||
| sb.append("第七步:合并5个文件").append(huanhangstr); | |||||
| sb.append(mergeTrainFiles(fontName)).append(huanhangstr); | |||||
| sb.append("............ ").append(huanhangstr); | |||||
| sb.append("第八步:将").append(fontName).append(".traineddata 文件拷贝到后端服务器ocr_data(项目配置fm.ocr_data)目录下。 .tif、。box、。tr文件也需要保留,后面如果这个字库有更新,需要用到这些文件。").append(huanhangstr); | |||||
| return sb.toString(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -39,6 +39,13 @@ | |||||
| <groupId>com.github.axet</groupId> | <groupId>com.github.axet</groupId> | ||||
| <artifactId>kaptcha</artifactId> | <artifactId>kaptcha</artifactId> | ||||
| <version>0.0.9</version> | <version>0.0.9</version> | ||||
| </dependency> | |||||
| <!-- ocr --> | |||||
| <dependency> | |||||
| <groupId>com.iformall</groupId> | |||||
| <artifactId>mallinkOcr</artifactId> | |||||
| <version>1.0</version> | |||||
| </dependency> | </dependency> | ||||
| </dependencies> | </dependencies> | ||||
| @@ -34,6 +34,9 @@ public class SysApplication { | |||||
| @Value("${fm.upload_dir}") | @Value("${fm.upload_dir}") | ||||
| private String uploadDir; | private String uploadDir; | ||||
| @Value("${fm.ocr_data}") | |||||
| private String ocrData; | |||||
| @Bean | @Bean | ||||
| public boolean isFmException() { | public boolean isFmException() { | ||||
| return fmException; | return fmException; | ||||
| @@ -0,0 +1,220 @@ | |||||
| package com.iformall.controller.ocr; | |||||
| import com.github.pagehelper.PageInfo; | |||||
| import com.iformall.annotation.SystemControllerLog; | |||||
| import com.iformall.common.ErrorCode; | |||||
| import com.iformall.common.Result; | |||||
| import com.iformall.common.ResultData; | |||||
| import com.iformall.controller.base.BaseController; | |||||
| import com.iformall.domain.po.MallUserInfo; | |||||
| import com.iformall.domain.po.WxMall; | |||||
| import com.iformall.domain.po.WxMerchant; | |||||
| import com.iformall.domain.po.WxMerchantOcrModel; | |||||
| import com.iformall.domain.po.WxOcrModel; | |||||
| import com.iformall.domain.po.base.TenantEntity; | |||||
| import com.iformall.domain.po.base.BaseEntity.SortField; | |||||
| import com.iformall.enums.EnumFromType; | |||||
| import com.iformall.enums.EnumRentStartType; | |||||
| import com.iformall.ocr.FormallTess4j; | |||||
| import com.iformall.ocr.FormallTess4jTrain; | |||||
| import com.iformall.service.WxMallService; | |||||
| import com.iformall.service.WxMerchantService; | |||||
| import com.iformall.service.WxOcrService; | |||||
| import io.swagger.annotations.ApiImplicitParam; | |||||
| import io.swagger.annotations.ApiImplicitParams; | |||||
| import io.swagger.annotations.ApiOperation; | |||||
| import java.io.File; | |||||
| import java.io.FileOutputStream; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.io.OutputStream; | |||||
| import java.util.Date; | |||||
| import java.util.Map; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.web.bind.annotation.*; | |||||
| import org.springframework.web.multipart.MultipartFile; | |||||
| @RestController | |||||
| @RequestMapping("ocr") | |||||
| public class WxOcrController extends BaseController { | |||||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||||
| @Autowired | |||||
| private WxOcrService ocrService; | |||||
| @Autowired | |||||
| private WxMerchantService merchantService; | |||||
| @Autowired | |||||
| private String ocrData; | |||||
| /** | |||||
| * 模板列表 | |||||
| * @param wxRentContract | |||||
| * @param pageNum | |||||
| * @param pageSize | |||||
| * @return | |||||
| */ | |||||
| @GetMapping("/modelList") | |||||
| @ApiImplicitParams({ | |||||
| @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), | |||||
| @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)}) | |||||
| public ResultData modelList(@ModelAttribute WxOcrModel ocrModel, Integer pageNum, Integer pageSize) { | |||||
| if (null == ocrModel) { | |||||
| ocrModel = new WxOcrModel(); | |||||
| } | |||||
| ocrModel.setSortColumns(SortField.Createtime_DESC); | |||||
| PageInfo<WxOcrModel> page = ocrService.listOcrModelAsPage(ocrModel, pageNum, pageSize); | |||||
| return new ResultData(page); | |||||
| } | |||||
| /** | |||||
| * 更新模板 | |||||
| * @param wxRentContract | |||||
| * @return | |||||
| */ | |||||
| @PostMapping("updateModel") | |||||
| public ResultData updateModel(@RequestBody WxOcrModel ocrModel) { | |||||
| return ocrService.saveOrUpdateOcrModel(ocrModel); | |||||
| } | |||||
| /** | |||||
| * 根据商户查询模板 | |||||
| * @param wxRentContract | |||||
| * @return | |||||
| */ | |||||
| @GetMapping("merchantModel") | |||||
| @ApiImplicitParams({ | |||||
| @ApiImplicitParam(name = "merchantId", value = "商户编号", dataType = "Long", paramType = "query", required = true) | |||||
| }) | |||||
| public ResultData merchantModel(Long merchantId) { | |||||
| WxMerchant merchant = merchantService.getById(merchantId); | |||||
| if (null == merchant) { | |||||
| return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),"商户数据不存在"); | |||||
| } | |||||
| return new ResultData(ocrService.getMerchantOcrModel(merchantId, merchant.getTenantId(), merchant.getParentTenantId())); | |||||
| } | |||||
| /** | |||||
| * 更新商户模板 | |||||
| * @param wxRentContract | |||||
| * @return | |||||
| */ | |||||
| @PostMapping("updateMerchantModel") | |||||
| public ResultData updateMerchantModel(@RequestBody WxMerchantOcrModel merchantModel) { | |||||
| return ocrService.saveOrUpdateMerchantOcrModel(merchantModel); | |||||
| } | |||||
| /** | |||||
| * 删除商户模板 | |||||
| * @param wxRentContract | |||||
| * @return | |||||
| */ | |||||
| @PostMapping("deleteMerchantModel") | |||||
| public ResultData deleteMerchantModel(@RequestBody WxMerchantOcrModel merchantModel) { | |||||
| return ocrService.deleteMerchantOcrModel(merchantModel.getId()); | |||||
| } | |||||
| /** | |||||
| * 获取训练步骤 | |||||
| * @return | |||||
| */ | |||||
| @GetMapping("getTrainSteps") | |||||
| @ApiImplicitParams({ | |||||
| @ApiImplicitParam(name = "modelId", value = "模板编号", dataType = "Long", paramType = "query", required = true) | |||||
| }) | |||||
| public ResultData getTrainSteps(Long modelId) { | |||||
| WxOcrModel model = ocrService.getOcrModelById(modelId); | |||||
| if (null == model) { | |||||
| return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),"ocr模板不存在"); | |||||
| } | |||||
| return new ResultData(FormallTess4jTrain.getTrainSteps(model.getLangCode(), model.getFontName())); | |||||
| } | |||||
| /** | |||||
| *测试训练结果 | |||||
| * @return | |||||
| */ | |||||
| @PostMapping(value = "/testTrain", consumes = "multipart/*", headers = "content-type=multipart/form-data") | |||||
| public ResultData testTrain(@RequestParam("file") MultipartFile multiReq,@RequestParam("modelId") Long modelId) { | |||||
| try { | |||||
| WxOcrModel model = ocrService.getOcrModelById(modelId); | |||||
| if (null == model) { | |||||
| return new ResultData(ErrorCode.SYS_SERVER_ERROR.getCode(),"ocr模板不存在"); | |||||
| } | |||||
| File file = multipartFileToFile(multiReq); | |||||
| String result = FormallTess4j.testDoOCR_File(ocrData, file, model.getFontName()); | |||||
| return new ResultData(result); | |||||
| } catch (Exception e) { | |||||
| logger.error("testTrain error.",e); | |||||
| return new ResultData(ErrorCode.PICTURE_ANALYZING_ERROR.getCode(),"解析失败。"+e.getMessage()); | |||||
| } | |||||
| } | |||||
| private File multipartFileToFile(MultipartFile file) { | |||||
| File toFile = null; | |||||
| if (file.equals("") || file.getSize() <= 0) { | |||||
| file = null; | |||||
| } else { | |||||
| InputStream ins = null; | |||||
| try { | |||||
| ins = file.getInputStream(); | |||||
| toFile = new File(file.getOriginalFilename()); | |||||
| inputStreamToFile(ins, toFile); | |||||
| ins.close(); | |||||
| } catch (IOException e) { | |||||
| logger.error("multipartFileToFile error.",e); | |||||
| }finally { | |||||
| if (null != ins) { | |||||
| try { | |||||
| ins.close(); | |||||
| } catch (IOException e) { | |||||
| logger.error("multipartFileToFile error.",e); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| return toFile; | |||||
| } | |||||
| private void inputStreamToFile(InputStream ins, File file) { | |||||
| OutputStream os = null; | |||||
| try { | |||||
| os = new FileOutputStream(file); | |||||
| 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(); | |||||
| } catch (Exception e) { | |||||
| logger.error("inputStreamToFile error.",e); | |||||
| }finally { | |||||
| if (null != os) { | |||||
| try { | |||||
| os.close(); | |||||
| } catch (IOException e) { | |||||
| logger.error("inputStreamToFile error.",e); | |||||
| } | |||||
| } | |||||
| if (null != ins) { | |||||
| try { | |||||
| ins.close(); | |||||
| } catch (IOException e) { | |||||
| logger.error("inputStreamToFile error.",e); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -165,6 +165,7 @@ fm: | |||||
| deploy: 1 | deploy: 1 | ||||
| open: true | open: true | ||||
| upload_dir: /home/test/server/uploads/ | upload_dir: /home/test/server/uploads/ | ||||
| ocr_data: /home/test/server/ocr_data/ | |||||
| ueditor: | ueditor: | ||||
| config: config.json | config: config.json | ||||
| @@ -122,12 +122,14 @@ fm: | |||||
| deploy: 3 | deploy: 3 | ||||
| open: true | open: true | ||||
| upload_dir: /root/uploads/ | upload_dir: /root/uploads/ | ||||
| ocr_data: /root/ocr_data/ | |||||
| ueditor: | ueditor: | ||||
| config: config.json | config: config.json | ||||
| unified: true | unified: true | ||||
| upload-path: ./upload/ | upload-path: ./upload/ | ||||
| url-prefix: "" | url-prefix: "" | ||||
| logging: | logging: | ||||
| level: | level: | ||||
| @@ -100,6 +100,7 @@ fm: | |||||
| deploy: 2 | deploy: 2 | ||||
| open: true | open: true | ||||
| upload_dir: /home/ec2-user/server/uploads/ | upload_dir: /home/ec2-user/server/uploads/ | ||||
| ocr_data: /home/ec2-user/server/ocr_data/ | |||||
| ueditor: | ueditor: | ||||
| config: config.json | config: config.json | ||||