最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
java实现图片文字识别ocr
时间:2022-06-29 01:23:59 编辑:袖梨 来源:一聚教程网
最近在开发的时候需要识别图片中的一些文字,网上找了相关资料之后,发现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(); } }
在实验中发现,如果对有多个文字的大图进行直接识别的话,效果可能比较差,所以可以参考另一篇切图的博文,将图片取一块之后再识别
这样成功率会提高很多。
相关文章
- 《燕云十六声》红尘无眼完成图文攻略 12-25
- 《燕云十六声》阴阳如影完成图文攻略 12-25
- 《燕云十六声》悬檐之下四架椽屋图文攻略 12-25
- 《燕云十六声》2024最新公测时间介绍 12-25
- 《燕云十六声》有没有藏宝阁 12-25
- 《燕云十六声》制作公司介绍 12-25