这里有新鲜出炉的 Java 并发编程示例,程序狗速度看过来!
Java 程序设计语言
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称.
这篇文章主要介绍了 java 实现图片文字识别 ocr ,非常具有实用价值,需要的朋友可以参考下
最近在开发的时候需要识别图片中的一些文字,网上找了相关资料之后,发现 google 有一个离线的工具,以下为 java 使用的 demo
在此之前,使用这个工具需要在本地安装 OCR 工具:
下面一个是一定要安装的离线包,建议默认安装
上面一个是中文的语言包,如果网络可以 FQ 的童鞋可以在安装的时候就选择语言包在线安装,有多种语言可供选择,默认只有英文的
exe 安装好之后,把上面一个文件拷到安装目录下 tessdata 文件夹下
如 C:\Program Files (x86)\Tesseract-OCR\tessdata 下
然后下面两个是可选包,如果图片不做临时文件处理的话,可以不需要带的
首先是一个临时文件生成用的类以防源文件损坏,参考某位博友的例子 @Gunner
下面是真正识别的内容:
package org.ink.image.textrz;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Locale;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
import com.sun.media.imageio.plugins.tiff.TIFFImageWriteParam;
public class ImageIOHelper {
private Locale locale = Locale.CHINESE;
/**
* user set locale Construct
* @param locale
*/
public ImageIOHelper(Locale locale) {
this.locale = locale;
}
/**
* default construct using default locale Locale.CHINESE
*/
public ImageIOHelper() {}
/**
* 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
*/
public File createImage(File imageFile, String imageFormat) throws IOException {
Iterator < ImageReader > readers = ImageIO.getImageReadersByFormatName(imageFormat);
ImageReader reader = readers.next();
ImageInputStream iis = ImageIO.createImageInputStream(imageFile);
reader.setInput(iis);
IIOMetadata streamMetadata = reader.getStreamMetadata();
TIFFImageWriteParam tiffWriteParam = new TIFFImageWriteParam(Locale.CHINESE);
tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);
Iterator < ImageWriter > writers = ImageIO.getImageWritersByFormatName("tiff");
ImageWriter writer = writers.next();
BufferedImage bi = reader.read(0);
IIOImage image = new IIOImage(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();
return tempFile;
}
/**
* add suffix to tempfile
* @param imageFile
* @return
* @throws IOException
*/
private File tempImageFile(File imageFile) throws IOException {
String path = imageFile.getPath();
StringBuffer strB = new StringBuffer(path);
strB.insert(path.lastIndexOf('.'), "_text_recognize_temp");
String s = strB.toString().replaceFirst("(?<=//.)(//w+)$", "tif");
Runtime.getRuntime().exec("attrib " + "\"" + s + "\"" + " +H"); //设置文件隐藏
return new File(strB.toString());
}
}
在实验中发现,如果对有多个文字的大图进行直接识别的话,效果可能比较差,所以可以参考另一篇切图的博文,将图片取一块之后再识别
package org.ink.image.textrz;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.jdesktop.swingx.util.OS;
/**
* TEXT Recognize Utils
* @author ink.Flower
*
*/
public class OCRUtil {
private final String LANG_OPTION = "-l"; //英文字母小写l,并非数字1
private final String EOL = System.getProperty("line.separator");
private String tessPath = "C://Program Files (x86)//Tesseract-OCR"; //ocr默认安装路径
private String 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
*/
public OCRUtil(String tessPath, String transFileName) {
this.tessPath = tessPath;
this.transname = transFileName;
}
/**
* Construct method of OCR,default path is "C://Program Files (x86)//Tesseract-OCR"
*/
public OCRUtil() {}
public String getTessPath() {
return tessPath;
}
public void setTessPath(String tessPath) {
this.tessPath = tessPath;
}
public String getTransname() {
return transname;
}
public void setTransname(String transname) {
this.transname = transname;
}
public String getLANG_OPTION() {
return LANG_OPTION;
}
public String getEOL() {
return EOL;
}
/**
* recognize text in image
* @param imageFile
* @param imageFormat
* @return text recognized in image
* @throws Exception
*/
public String recognizeText(File imageFile, String imageFormat) throws Exception {
File tempImage = new ImageIOHelper().createImage(imageFile, imageFormat);
return ocrImages(tempImage, imageFile);
}
/**
* recognize text in image
* @param imageFile
* @param imageFormat
* @param locale
* @return text recognized in image
* @throws Exception
*/
public String recognizeText(File imageFile, String imageFormat, Locale locale) throws Exception {
File tempImage = new ImageIOHelper(locale).createImage(imageFile, imageFormat);
return ocrImages(tempImage, imageFile);
}
/**
*
* @param tempImage
* @param imageFile
* @return
* @throws IOException
* @throws InterruptedException
*/
private String ocrImages(File tempImage, File imageFile) throws IOException,
InterruptedException {
File outputFile = new File(imageFile.getParentFile(), "output");
Runtime.getRuntime().exec("attrib " + "\"" + outputFile.getAbsolutePath() + "\"" + " +H"); //设置文件隐藏
StringBuffer strB = new StringBuffer();
List < String > cmd = new ArrayList < String > ();
if (OS.isWindowsXP()) {
cmd.add(tessPath + "//tesseract");
} else if (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 = new ProcessBuilder();
pb.directory(imageFile.getParentFile());
cmd.set(1, tempImage.getName());
pb.command(cmd);
pb.redirectErrorStream(true);
Process process = pb.start();
int w = process.waitFor();
tempImage.delete(); //删除临时正在工作文件
if (w == 0) {
BufferedReader in =new BufferedReader(new InputStreamReader(new FileInputStream(outputFile.getAbsolutePath() + ".txt"), "UTF-8"));
String str;
while ((str = in.readLine()) != null) {
strB.append(str).append(EOL);
} in .close();
} else {
String msg;
switch (w) {
case 1:
msg = "Errors accessing files.There may be spaces in your image's filename.";
break;
case 29:
msg = "Cannot recongnize the image or its selected region.";
break;
case 31:
msg = "Unsupported image format.";
break;
default:
msg = "Errors occurred.";
}
tempImage.delete();
throw new RuntimeException(msg);
}
new File(outputFile.getAbsolutePath() + ".txt").delete();
return strB.toString();
}
}
/article/17/1108/355063.html ←我是链接
这样成功率会提高很多.
以上为离线识别版本,效率因图而已,具体使用的时候可以总结分析,希望对大家的学习有所帮助,也希望大家多多支持 PHPERZ.
来源: http://www.phperz.com/article/18/0116/355057.html