Java 图片提取验证码 https://my.oschina.net/gaoguofan/blog/800197
安装 Tesseract-OCR
Windows 版本
- tesseract-ocr-setup-xx.xx.exe
- chi_sim.traineddata.gz 中文语言包
这两个请自行百度即可,然后我们将其安装在D:下,其中将语言包放在安装目录下的tessdata的目录下。
Linux 版本
我使用的是centos7,下面给出安装tesseract的前提条件。
- 安装编译库
12yum install autoconf automake libtoolyum install libjpeg-devel libpng-devel libtiff-devel zlib-devel
请注意这里面是两个库,使用了顿号隔开的,一般系统都有存在这个库的 - 安装依赖的leptonica库
1234wget http://www.leptonica.com/source/leptonica-1.72.tar.gztar -xvf leptonica-1.72.tar.gzcd leptonica-1.72./configure --with-libpng && make && make install
这个依赖库要注意,一定是1.71以上的版本。 - 下载编译tesseract
12345678wget https://github.com/tesseract-ocr/tesseract/archive/3.04.00.tar.gzmv 3.04.00 Tesseract3.04.00.tar.gztar -xvf Tesseract3.04.00.tar.gzcd tesseract-3.04.00/./autogen.sh./configuremake && make installldconfig
tesseract我安装在了 /usr/local 这个目录下,名称为 tesseract-3.04.00 。如果你使用的是3.01的版本,需要在./autogen.sh 后面执行mkdir m4;这条命令,否则他会提示m4这个目录不存在。 - 下载识别库(语言包)
1234wget --no-check-certificate https://github.com/tesseract-ocr/tessdata/raw/master/eng.traineddatawget --no-check-certificate https://github.com/tesseract-ocr/tessdata/raw/master/chi_sim.traineddatawget --no-check-certificate https://github.com/tesseract-ocr/tessdata/raw/master/chi_tra.traineddatawget http://tesseract-ocr.googlecode.com/files/tesseract-ocr-3.02.eng.tar.gz
注意此处的语言包以及解压出的语言包都要放在 /usr/local/share/tessdata/ 目录下。
Java 读取数据
- 启动命令程序
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112package com.zefun.common.utils;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.List;import org.apache.log4j.Logger;import org.jdesktop.swingx.util.OS;/*** ocr 读取命令程序* @author 高国藩* @date 2016年12月5日 上午10:27:16*/public class Ocr {/** 英文字母小写l,并非数字1 */private static final String LANG_OPTION = "-l";/** 系统换行符 */private static final String EOL = System.getProperty("line.separator");/** 系统目录符 */private static final String GNL = System.getProperty("file.separator");/** log */private Logger logger = Logger.getLogger(Ocr.class);/** 目标,下面分别为Linux和Windows下的程序配备,Linux不需要此处的路径了 */// private String tessPath = GNL + "usr" + GNL + "local" + GNL + "tesseract-3.04.00";private String tessPath = new File("D:\\Tesseract-OCR").getAbsolutePath();/*** 解析图片* @author 高国藩* @date 2016年12月5日 上午10:28:47* @param imageFile image file* @param imageFormat 转码路径* @return ver_code* @throws Exception 异常处理啊*/public String recognizeText(File imageFile, String imageFormat) throws Exception {File tempImage = ImageIOHelper.createImage(imageFile, imageFormat);File outputFile = new File(imageFile.getParentFile(), "output");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("chi_sim"); 更换语言包cmd.add("eng");ProcessBuilder pb = new ProcessBuilder();pb.directory(imageFile.getParentFile());cmd.set(1, tempImage.getName());pb.command(cmd);pb.redirectErrorStream(true);Process process = pb.start();logger.info(cmd.toString());// tesseract.exe 1.jpg 1 -l chi_simint 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();logger.info("图形识别结果 ====>>> " + strB.toString());return strB.toString();}}
此处要注意一下tesseract的命令目录,Windows和Linux的目录不同,尤其分隔符。 - 解析图片程序
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485package com.zefun.common.utils;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;/*** ver_image 图片解析器* @author 高国藩* @date 2016年12月5日 上午10:31:09*/public class ImageIOHelper {/*** 图片文件转换为tif格式* @param imageFile 文件路径* @param imageFormat 文件扩展名* @return 路径*/public static File createImage(File imageFile, String imageFormat) {File tempFile = null;try {Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(imageFormat);ImageReader reader = readers.next();ImageInputStream iis = ImageIO.createImageInputStream(imageFile);reader.setInput(iis);// Read the stream metadataIIOMetadata streamMetadata = reader.getStreamMetadata();// Set up the writeParamTIFFImageWriteParam tiffWriteParam = new TIFFImageWriteParam(Locale.CHINESE);tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);// Get tif writer and set output to fileIterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("tiff");ImageWriter writer = writers.next();BufferedImage bi = reader.read(0);IIOImage image = new IIOImage(bi, null, reader.getImageMetadata(0));tempFile = tempImageFile(imageFile);ImageOutputStream ios = ImageIO.createImageOutputStream(tempFile);writer.setOutput(ios);writer.write(streamMetadata, image, tiffWriteParam);ios.close();writer.dispose();reader.dispose();}catch (IOException e) {e.printStackTrace();}return tempFile;}/*** 格式化图片* @author 高国藩* @date 2016年12月5日 上午10:31:41* @param imageFile imageFile* @return File*/private static File tempImageFile(File imageFile) {String path = imageFile.getPath();StringBuffer strB = new StringBuffer(path);strB.insert(path.lastIndexOf('.'), 0);return new File(strB.toString().replaceFirst("(?<=//.)(//w+)$", "tif"));}}
改程序会将图片首先解析为tif类型文件,在其中读取出数据。 - 测试加载
12String valCode = new Ocr().recognizeText(new File(new File(path4).getAbsolutePath()), "jpg");logger.info(valCode);
注意在测试中的文件路径问题,Linux和Windows区别很大。 - Maven 包管理
-
123456789101112131415161718192021<dependency><groupId>net.java.dev.jna</groupId><artifactId>jna</artifactId><version>4.2.1</version></dependency><dependency><groupId>net.sourceforge.tess4j</groupId><artifactId>tess4j</artifactId><version>2.0.1</version><exclusions><exclusion><groupId>com.sun.jna</groupId><artifactId>jna</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.kenai.nbpwr</groupId><artifactId>org-jdesktop-swingx</artifactId><version>1.6-201002261215</version></dependency>