最近在开发的时候需要识别图片中的一些文字,网上找了相关资料之后,发现google有一个离线的工具,以下为java使用的demo
在此之前,使用这个工具需要在本地安装OCR工具:
下面一个是一定要安装的离线包,建议默认安装
上面一个是中文的语言包,如果网络可以FQ的童鞋可以在安装的时候就选择语言包在线安装,有多种语言可供选择,默认只有英文的
exe安装好之后,把上面一个文件拷到安装目录下tessdata文件夹下
如C:Program Files (x86)Tesseract-OCRtessdata下
然后下面两个是可选包,如果图片不做临时文件处理的话,可以不需要带的
首先是一个临时文件生成用的类以防源文件损坏,参考某位博友的例子@Gunner
packageorg.ink.image.textrz; importjava.awt.image.BufferedImage; importjava.io.File; importjava.io.IOException; importjava.util.Iterator; importjava.util.Locale; importjavax.imageio.IIOImage; importjavax.imageio.ImageIO; importjavax.imageio.ImageReader; importjavax.imageio.ImageWriteParam; importjavax.imageio.ImageWriter; importjavax.imageio.metadata.IIOMetadata; importjavax.imageio.stream.ImageInputStream; importjavax.imageio.stream.ImageOutputStream; importcom.sun.media.imageio.plugins.tiff.TIFFImageWriteParam; publicclassImageIOHelper { privateLocale locale=Locale.CHINESE; /** * user set locale Construct * @param locale */ publicImageIOHelper(Locale locale){ this.locale=locale; } /** * default construct using default locale Locale.CHINESE */ publicImageIOHelper(){ } /** * create tempFile of Image in order to prevent damaging original file * @param imageFile * @param imageFormat like png,jps .etc * @return TempFile of Image * @throws IOException */ publicFile createImage(File imageFile, String imageFormat)throwsIOException { Iteratorreaders = ImageIO.getImageReadersByFormatName(imageFormat); ImageReader reader = readers.next(); ImageInputStream iis = ImageIO.createImageInputStream(imageFile); reader.setInput(iis); IIOMetadata streamMetadata = reader.getStreamMetadata(); TIFFImageWriteParam tiffWriteParam =newTIFFImageWriteParam(Locale.CHINESE); tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED); Iterator writers = ImageIO.getImageWritersByFormatName("tiff"); ImageWriter writer = writers.next(); BufferedImage bi = reader.read(0); IIOImage image =newIIOImage(bi,null,reader.getImageMetadata(0)); File tempFile = tempImageFile(imageFile); ImageOutputStream ios = ImageIO.createImageOutputStream(tempFile); writer.setOutput(ios); writer.write(streamMetadata, image, tiffWriteParam); ios.close(); iis.close(); writer.dispose(); reader.dispose(); returntempFile; } /** * add suffix to tempfile * @param imageFile * @return * @throws IOException */ privateFile tempImageFile(File imageFile)throwsIOException { String path = imageFile.getPath(); StringBuffer strB =newStringBuffer(path); strB.insert(path.lastIndexOf('.'),"_text_recognize_temp"); String s=strB.toString().replaceFirst("(?<=//.)(//w+)$","tif"); Runtime.getRuntime().exec("attrib "+"""+s+"""+" +H");//设置文件隐藏 returnnewFile(strB.toString()); } }
下面是真正识别的内容:
packageorg.ink.image.textrz; importjava.io.BufferedReader; importjava.io.File; importjava.io.FileInputStream; importjava.io.IOException; importjava.io.InputStreamReader; importjava.util.ArrayList; importjava.util.List; importjava.util.Locale; importorg.jdesktop.swingx.util.OS; /** * TEXT Recognize Utils * @author ink.Flower * */ publicclassOCRUtil { privatefinalString LANG_OPTION ="-l";//英文字母小写l,并非数字1 privatefinalString EOL = System.getProperty("line.separator"); privateString tessPath ="C://Program Files (x86)//Tesseract-OCR";//ocr默认安装路径 privateString transname="chi_sim";//默认中文语言包,识别中文 /** * Construct method of OCR ,set Tesseract-OCR install path * @param tessPath Tesseract-OCR install path * @param transFileName traningFile name like eng.traineddata */ publicOCRUtil(String tessPath,String transFileName){ this.tessPath=tessPath; this.transname=transFileName; } /** * Construct method of OCR,default path is "C://Program Files (x86)//Tesseract-OCR" */ publicOCRUtil(){ } publicString getTessPath() { returntessPath; } publicvoidsetTessPath(String tessPath) { this.tessPath = tessPath; } publicString getTransname() { returntransname; } publicvoidsetTransname(String transname) { this.transname = transname; } publicString getLANG_OPTION() { returnLANG_OPTION; } publicString getEOL() { returnEOL; } /** * recognize text in image * @param imageFile * @param imageFormat * @return text recognized in image * @throws Exception */ publicString recognizeText(File imageFile,String imageFormat)throwsException{ File tempImage =newImageIOHelper().createImage(imageFile,imageFormat); returnocrImages(tempImage, imageFile); } /** * recognize text in image * @param imageFile * @param imageFormat * @param locale * @return text recognized in image * @throws Exception */ publicString recognizeText(File imageFile,String imageFormat,Locale locale)throwsException{ File tempImage =newImageIOHelper(locale).createImage(imageFile,imageFormat); returnocrImages(tempImage, imageFile); } /** * * @param tempImage * @param imageFile * @return * @throws IOException * @throws InterruptedException */ privateString ocrImages(File tempImage,File imageFile)throwsIOException, InterruptedException{ File outputFile =newFile(imageFile.getParentFile(),"output"); Runtime.getRuntime().exec("attrib "+"""+outputFile.getAbsolutePath()+"""+" +H");//设置文件隐藏 StringBuffer strB =newStringBuffer(); Listcmd =newArrayList (); if(OS.isWindowsXP()){ cmd.add(tessPath+"//tesseract"); }elseif(OS.isLinux()){ cmd.add("tesseract"); }else{ cmd.add(tessPath+"//tesseract"); } cmd.add(""); cmd.add(outputFile.getName()); cmd.add(LANG_OPTION); cmd.add(transname); ProcessBuilder pb =newProcessBuilder(); pb.directory(imageFile.getParentFile()); cmd.set(1, tempImage.getName()); pb.command(cmd); pb.redirectErrorStream(true); Process process = pb.start(); intw = process.waitFor(); tempImage.delete();//删除临时正在工作文件 if(w==0){ BufferedReader in =newBufferedReader(newInputStreamReader(newFileInputStream(outputFile.getAbsolutePath()+".txt"),"UTF-8")); String str; while((str = in.readLine())!=null){ strB.append(str).append(EOL); } in.close(); }else{ String msg; switch(w){ case1: msg ="Errors accessing files.There may be spaces in your image's filename."; break; case29: msg ="Cannot recongnize the image or its selected region."; break; case31: msg ="Unsupported image format."; break; default: msg ="Errors occurred."; } tempImage.delete(); thrownewRuntimeException(msg); } newFile(outputFile.getAbsolutePath()+".txt").delete(); returnstrB.toString(); } }
在实验中发现,如果对有多个文字的大图进行直接识别的话,效果可能比较差,所以可以参考另一篇切图的博文,将图片取一块之后再识别
这样成功率会提高很多。
忍者必须死34399账号登录版 最新版v1.0.138v2.0.72
下载勇者秘境oppo版 安卓版v1.0.5
下载忍者必须死3一加版 最新版v1.0.138v2.0.72
下载绝世仙王官方正版 最新安卓版v1.0.49
下载Goat Simulator 3手机版 安卓版v1.0.8.2
Goat Simulator 3手机版是一个非常有趣的模拟游
Goat Simulator 3国际服 安卓版v1.0.8.2
Goat Simulator 3国际版是一个非常有趣的山羊模
烟花燃放模拟器中文版 2025最新版v1.0
烟花燃放模拟器是款仿真的烟花绽放模拟器类型单机小游戏,全方位
我的世界动漫世界 手机版v友y整合
我的世界动漫世界模组整合包是一款加入了动漫元素的素材整合包,
我的世界贝爷生存整合包 最新版v隔壁老王
我的世界MITE贝爷生存整合包是一款根据原版MC制作的魔改整