使用谷歌开源组件tesseract-OCR识别身份证,通过opencv处理图像后再进行识别(windows版本)

1,前面有一篇已经介绍tesseract-OCR的简单实用和识别,因识别率不高,特意将图片实用opencv处理后,再次进行识别,经过测试,识别率高了30%左右

2,实用opcv整合tesseract-OCR需要的jar包,此处的识别已经不再通过调用windows系统命令,而通过tesseract-OCR工具类tess4j.jar完成。(实际上tess4j也是调用系统命令)

使用谷歌开源组件tesseract-OCR识别身份证,通过opencv处理图像后再进行识别(windows版本)_第1张图片

3,注意到上面有个opencv_java320.dll(32位和64位,根据你的jdk决定,到时我发现在这儿其实好像加载不到,所以使用一下方法)

将opencv_java320.dll加入到系统库的Native library location(如图)

使用谷歌开源组件tesseract-OCR识别身份证,通过opencv处理图像后再进行识别(windows版本)_第2张图片

4,上代码,学过java的一看就明白

package com.njupt.zhb.test;

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 net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;

/**
 * @author  zwp
 * @date 创建时间:2017年3月24日 下午5:12:12 
 * @version 2.0 
 * @parameter
 * @since  
 * @return 
 */
public class Test {
	
	 public static String test(String path) {
		File imageFile=new File(path);
		
		Tesseract instance=Tesseract.getInstance();
		instance.setDatapath("C:\\Program Files (x86)\\Tesseract-OCR\\tessdata");//设置训练库的位置
		//instance.setLanguage("chi_sim");//中文识别
		instance.setLanguage("eng");//中文识别
		try {
			String result = instance.doOCR(imageFile);
			System.out.println(result);
			return result;
		} catch (TesseractException e) {
			e.printStackTrace();
		}
		return "";
	}

	private final String LANG_OPTION = "-l";
	    private final String EOL = System.getProperty("line.separator");
	    /**
	     * 文件位置我防止在,项目同一路径
	     */
	    private String tessPath = new File("tesseract").getAbsolutePath();

	    /**
	     * @param imageFile
	     *            传入的图像文件
	     * @param imageFormat
	     *            传入的图像格式
	     * @return 识别后的字符串
	     */
	    public String recognizeText(File imageFile) throws Exception
	    {
	        /**
	         * 设置输出文件的保存的文件目录
	         */
	        File outputFile = new File(imageFile.getParentFile(), "output");

	        StringBuffer strB = new StringBuffer();
	        List cmd = new ArrayList();

	        String os = System.getProperty("os.name");
	        if(os.toLowerCase().startsWith("win")){
	            cmd.add("tesseract");
	        }else {
	            cmd.add("tesseract");
	        }
//	        cmd.add(tessPath + "\\tesseract");
	        cmd.add(imageFile.getName());
	        cmd.add(outputFile.getName());
//	        cmd.add(LANG_OPTION);
//	      cmd.add("chi_sim");
	        cmd.add("digits");
//	        cmd.add("eng");
//	        cmd.add("-psm 7");
	        ProcessBuilder pb = new ProcessBuilder();

	        /**
	         *Sets this process builder's working directory.
	         */
	        pb.directory(imageFile.getParentFile());
//	        cmd.set(1, imageFile.getName());
	        pb.command(cmd);
	        pb.redirectErrorStream(true);
	        Process process = pb.start();

//	        Process process = pb.command("ipconfig").start();
//	        System.out.println(System.getenv().get("Path"));
//	        Process process = pb.command("D:\\Program Files (x86)\\Tesseract-OCR\\tesseract.exe",imageFile.getName(),outputFile.getName(),LANG_OPTION,"eng").start();

	        // tesseract.exe 1.jpg 1 -l chi_sim
	        // Runtime.getRuntime().exec("tesseract.exe 1.jpg 1 -l chi_sim");
	        /**
	         * the exit value of the process. By convention, 0 indicates normal
	         * termination.
	         */
//	      System.out.println(cmd.toString());
	        int w = process.waitFor();
	        if (w == 0)// 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 recognize the image or its selected region.";
	                    break;
	                case 31:
	                    msg = "Unsupported image format.";
	                    break;
	                default:
	                    msg = "Errors occurred.";
	            }
	            throw new RuntimeException(msg);
	        }
	        new File(outputFile.getAbsolutePath() + ".txt").delete();
	        return strB.toString().replaceAll("\\s*", "");
	    }
	    /*public static void main(String[] args) throws Exception {
	        Tesseract("d:\\2.png");
	        Tesseract("/2.png");
	        Tesseract("/3.png");
	        Tesseract("/4.png");
	        Tesseract("/5.png");
	        Tesseract("/6.png");
	    }
*/
	    private static void Tesseract(String fileString) throws Exception {
	       // String filePath = Test.class.getResource(fileString).getFile().toString();
//	        processImg(filePath);
	        File file = new File(fileString);
	        String recognizeText = new Test().recognizeText(file);
	        System.out.println(recognizeText);
	    }
}

package com.njupt.zhb.test;

import java.awt.Image;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.ImageInputStream;

import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.objdetect.CascadeClassifier;


public class Main {
	private static final Double avatarSpacePer = 0.16;
	private static final Double avatarPer = 0.28;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		/*
		 * System.loadLibrary("opencv_java320"); Mat m = Mat.eye(3, 3,
		 * CvType.CV_8UC1); System.out.println("m = " + m.dump());
		 */
		System.loadLibrary("opencv_java320");
		/*
		 * Mat mat = Imgcodecs.imread("d:/data/1.jpg"); System.out.println(mat);
		 */
		File file = new File("d:/data");
		if (file.isDirectory()) {
			File[] files = file.listFiles();
			for (File f : files) {
				test(f.getPath());
			}
		}
		// test("d:/data/1.png");
	}

	private static void test(String fileName) {
		int index = fileName.lastIndexOf("\\");
		String suffix = index != -1 ? fileName.substring(index + 1) : ".png";
		int[] rectPosition = detectFace(fileName);
		System.out.println("x=" + rectPosition[0] + " y=" + rectPosition[1] + " width=" + rectPosition[2] + " height="
				+ rectPosition[3]);

		int x = rectPosition[0];
		int y = rectPosition[1];
		int w = rectPosition[2];
		int h = rectPosition[3];
		int[] imgRect = new int[2];
		try {
			imgRect = getImageWidth(fileName);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		/*
		 * if(x == 0 || y == 0 || w == 0 || h == 0 ){
		 * System.out.println("人脸识别失败:" + fileName + " 把身份证变成黑白照片再次进行识别");
		 * String destFile = "d:/data/temp" + suffix;
		 * //convertBackWhiteImage(fileName, destFile); changeImge(new
		 * File(fileName)); rectPosition = detectFace(fileName); // rectPosition
		 * = detectFace(destFile); System.out.println("x=" + rectPosition[0] +
		 * " y=" + rectPosition[1] + " width=" + rectPosition[2] + " height=" +
		 * rectPosition[3]);
		 * 
		 * x = rectPosition[0]; y = rectPosition[1]; w = rectPosition[2]; h =
		 * rectPosition[3]; }
		 */
		if (x == 0 || y == 0 || w == 0 || h == 0) {

			x = imgRect[0];
			y = imgRect[1];
			w = (int) (x * avatarPer);
			h = w;
			System.out.println("人脸识别失败:" + fileName + " 采用默认识别");

		}
		/*
		 * int cutX = x/4 + 20; int cutY = (y + h ) *2;
		 */
		int cutX = x / 2 - 20;

		String destFile = "d:/data/idcard" + suffix;

		int width = imgRect[0] - cutX - 30;
		// ImageUtils.cut(fileName, destFile, cutX, cutY, width/2, 120);
		// ImageUtils.cut(fileName, "d:/data/avatar.jpg", x, y, w, h);
		int cutHeight = 140;
		int imgHieght = imgRect[1];
		int topSpace = (int) (imgHieght * avatarPer);
		int height = (int) (imgHieght * avatarSpacePer);
		int cutY = y + h + height;
		if (imgHieght - cutY < cutHeight - 5) {
			cutY = imgHieght - (int) (imgHieght / 3.8) - 10;
		}
		if (imgHieght < 500) {
			cutY = cutY + 20;
		}
		new Main().cutImage(fileName, destFile, cutX, cutY, width, cutHeight);
		Test.test(destFile);
	}


	/**
	 * 图片转换成黑白图片
	 * 
	 * @param fileName
	 * @param destFile
	 */
	public static void convertBackWhiteImage(String fileName, String destFile) {
		OutputStream output = null;
		String suffix = null;
		String types = Arrays.toString(ImageIO.getReaderFormatNames()).replace("]", ",");
		// 获取图片后缀
		if (fileName.indexOf(".") > -1) {
			suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
		} // 类型和图片后缀全部小写,然后判断后缀是否合法
		if (suffix == null || types.toLowerCase().indexOf(suffix.toLowerCase() + ",") < 0) {
			return;
		}
		try {
			BufferedImage sourceImg = replaceWithWhiteColor(ImageIO.read(new FileInputStream(fileName)));
			output = new FileOutputStream(destFile);
			ImageIO.write(sourceImg, suffix, output);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (output != null)
				try {
					output.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
	}

	/**
	 * 把图像处理成黑白照片
	 * 
	 * @param bi
	 * @return
	 */
	public static BufferedImage replaceWithWhiteColor(BufferedImage bi) {

		int[] rgb = new int[3];

		int width = bi.getWidth();

		int height = bi.getHeight();

		int minx = bi.getMinX();

		int miny = bi.getMinY();

		/**
		 * 
		 * 遍历图片的像素,为处理图片上的杂色,所以要把指定像素上的颜色换成目标白色 用二层循环遍历长和宽上的每个像素
		 * 
		 */

		int hitCount = 0;

		for (int i = minx; i < width - 1; i++) {

			for (int j = miny; j < height; j++) {

				/**
				 * 
				 * 得到指定像素(i,j)上的RGB值,
				 * 
				 */

				int pixel = bi.getRGB(i, j);

				int pixelNext = bi.getRGB(i + 1, j);

				/**
				 * 
				 * 分别进行位操作得到 r g b上的值
				 * 
				 */

				rgb[0] = (pixel & 0xff0000) >> 16;

				rgb[1] = (pixel & 0xff00) >> 8;

				rgb[2] = (pixel & 0xff);

				/**
				 * 
				 * 进行换色操作,我这里是要换成白底,那么就判断图片中rgb值是否在范围内的像素
				 * 
				 */

				// 经过不断尝试,RGB数值相互间相差15以内的都基本上是灰色,

				// 对以身份证来说特别是介于73到78之间,还有大于100的部分RGB值都是干扰色,将它们一次性转变成白色

				if ((Math.abs(rgb[0] - rgb[1]) < 15)

						&& (Math.abs(rgb[0] - rgb[2]) < 15)

						&& (Math.abs(rgb[1] - rgb[2]) < 15) &&

						(((rgb[0] > 73) && (rgb[0] < 78)) || (rgb[0] > 100))) {

					// 进行换色操作,0xffffff是白色

					bi.setRGB(i, j, 0xffffff);

				}

			}

		}

		return bi;

	}

	public static int[] getImageWidth(String fileName) throws FileNotFoundException, IOException {
		File picture = new File(fileName);
		BufferedImage sourceImg = ImageIO.read(new FileInputStream(picture));
		int[] imgRect = new int[2];
		imgRect[0] = sourceImg.getWidth();
		imgRect[1] = sourceImg.getHeight();
		return imgRect;
	}

	public static int[] detectFace(String fileName) {
		int[] rectPosition = new int[4];
		CascadeClassifier faceDetector = new CascadeClassifier("./data/lbpcascade_frontalface.xml");
		Mat image = Imgcodecs.imread(fileName);
		MatOfRect faceDetections = new MatOfRect();
		Size minSize = new Size(120, 120);

		Size maxSize = new Size(250, 250);
		faceDetector.detectMultiScale(image, faceDetections, 1.1f, 4, 0, minSize, maxSize);

		System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));
		for (Rect rect : faceDetections.toArray()) {
			System.out.println(rect.toString());
			rectPosition[0] = rect.x;
			rectPosition[1] = rect.y;
			rectPosition[2] = rect.width;
			rectPosition[3] = rect.height;
		}

		/*
		 * String filename = "d:/data/avatar.jpg";
		 * System.out.println(String.format("Writing %s", filename));
		 * Imgcodecs.imwrite(filename, image);
		 */
		return rectPosition;
	}

	/**
	 * 

* Title: cutImage *

*

* Description: 根据原图与裁切size截取局部图片 *

* * @param srcImg * 源图片 * @param output * 图片输出流 * @param rect * 需要截取部分的坐标和大小 */ public void cutImage(File srcImg, File destImg, java.awt.Rectangle rect) { if (srcImg.exists()) { java.io.FileInputStream fis = null; ImageInputStream iis = null; OutputStream output = null; try { fis = new FileInputStream(srcImg); // ImageIO 支持的图片类型 : [BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, // JPEG, WBMP, GIF, gif] String types = Arrays.toString(ImageIO.getReaderFormatNames()).replace("]", ","); String suffix = null; // 获取图片后缀 if (srcImg.getName().indexOf(".") > -1) { suffix = srcImg.getName().substring(srcImg.getName().lastIndexOf(".") + 1); } // 类型和图片后缀全部小写,然后判断后缀是否合法 if (suffix == null || types.toLowerCase().indexOf(suffix.toLowerCase() + ",") < 0) { return; } // 将FileInputStream 转换为ImageInputStream iis = ImageIO.createImageInputStream(fis); // 根据图片类型获取该种类型的ImageReader ImageReader reader = ImageIO.getImageReaders(new FileImageInputStream(srcImg)).next(); // ImageIO.getImageReadersBySuffix(suffix).next(); reader.setInput(iis, true); ImageReadParam param = reader.getDefaultReadParam(); param.setSourceRegion(rect); BufferedImage bi = reader.read(0, param); output = new FileOutputStream(destImg); ImageIO.write(bi, suffix, output); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (fis != null) fis.close(); if (iis != null) iis.close(); if (output != null) output.close(); } catch (IOException e) { e.printStackTrace(); } } } else { } } public void cutImage(String srcImg, String destImg, int x, int y, int width, int height) { cutImage(new File(srcImg), new File(destImg), new java.awt.Rectangle(x, y, width, height)); } }
package com.njupt.zhb.test.util;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Logger;

import javax.imageio.ImageIO;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import com.alibaba.simpleimage.ImageRender;
import com.alibaba.simpleimage.SimpleImageException;
import com.alibaba.simpleimage.render.ReadRender;
import com.alibaba.simpleimage.render.ScaleParameter;
import com.alibaba.simpleimage.render.ScaleRender;
import com.alibaba.simpleimage.render.WriteRender;

/**
 * 图片处理工具类:
* 功能:缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等 * */ public class ImageUtils { // 缩略图宽度 public static int SMALL_IMG_WIDTH = 240; // 缩略图高度 public static int SMALL_IMG_HEIGHT = 240; static { System.setProperty("com.sun.media.jai.disableMediaLib", "true"); } /** * 几种常见的图片格式 */ public static String IMAGE_TYPE_GIF = "gif";// 图形交换格式 public static String IMAGE_TYPE_JPG = "jpg";// 联合照片专家组 public static String IMAGE_TYPE_JPEG = "jpeg";// 联合照片专家组 public static String IMAGE_TYPE_BMP = "bmp";// 英文Bitmap(位图)的简写,它是Windows操作系统中的标准图像文件格式 public static String IMAGE_TYPE_PNG = "png";// 可移植网络图形 public static String IMAGE_TYPE_PSD = "psd";// Photoshop的专用格式Photoshop /** * 检查图片类型 * * @param fileFileName2 * @return * */ public static boolean checkType(String fileFileName) { if (StringUtils.isBlank(fileFileName)) { return false; } fileFileName = fileFileName.toLowerCase(); if ((!fileFileName.endsWith(IMAGE_TYPE_GIF) && !fileFileName.endsWith(IMAGE_TYPE_JPG) && !fileFileName.endsWith(IMAGE_TYPE_JPEG) && !fileFileName.endsWith(IMAGE_TYPE_BMP) && !fileFileName.endsWith(IMAGE_TYPE_PNG) && !fileFileName.endsWith(IMAGE_TYPE_PSD))) { return false; } return true; } /** * 程序入口:用于测试 * * @param args */ public static void main2(String[] args) { // 1-缩放图像: // 方法一:按比例缩放 ImageUtils.scale("e:/abc.jpg", "e:/abc_scale.jpg", 2, true);// 测试OK // 方法二:按高度和宽度缩放 ImageUtils.scale2("e:/abc.jpg", "e:/abc_scale2.jpg", 500, 300, true);// 测试OK // 2-切割图像: // 方法一:按指定起点坐标和宽高切割 ImageUtils.cut("e:/abc.jpg", "e:/abc_cut.jpg", 0, 0, 400, 400);// 测试OK // 方法二:指定切片的行数和列数 ImageUtils.cut2("e:/abc.jpg", "e:/", 2, 2);// 测试OK // 方法三:指定切片的宽度和高度 ImageUtils.cut3("e:/abc.jpg", "e:/", 300, 300);// 测试OK // 3-图像类型转换: ImageUtils.convert("e:/abc.jpg", "GIF", "e:/abc_convert.gif");// 测试OK // 4-彩色转黑白: ImageUtils.gray("e:/abc.jpg", "e:/abc_gray.jpg");// 测试OK // 5-给图片添加文字水印: // 方法一: ImageUtils.pressText("我是水印文字", "e:/abc.jpg", "e:/abc_pressText.jpg", "宋体", Font.BOLD, Color.white, 80, 0, 0, 0.5f);// 测试OK // 方法二: ImageUtils.pressText2("我也是水印文字", "e:/abc.jpg", "e:/abc_pressText2.jpg", "黑体", 36, Color.white, 80, 0, 0, 0.5f);// 测试OK // 6-给图片添加图片水印: ImageUtils.pressImage("e:/abc2.jpg", "e:/abc.jpg", "e:/abc_pressImage.jpg", 0, 0, 0.5f);// 测试OK } /** * 缩放图像(按比例缩放) * * @param srcImageFile * 源图像文件地址 * @param result * 缩放后的图像地址 * @param scale * 缩放比例 * @param flag * 缩放选择:true 放大; false 缩小; */ public final static void scale(String srcImageFile, String result, int scale, boolean flag) { try { synchronized (ImageUtils.class) { BufferedImage src = ImageIO.read(new File(srcImageFile)); // 读入文件 int width = src.getWidth(); // 得到源图宽 int height = src.getHeight(); // 得到源图长 if (flag) {// 放大 width = width * scale; height = height * scale; } else {// 缩小 int wScale = width / SMALL_IMG_WIDTH; int hScale = height / SMALL_IMG_HEIGHT; scale = wScale > hScale ? hScale : wScale; scale = scale < 1 ? 1 : scale; width = width / scale; height = height / scale; } Image image = src.getScaledInstance(width, height, Image.SCALE_DEFAULT); BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(image, 0, 0, null); // 绘制缩小后的图 g.dispose(); ImageIO.write(tag, "JPEG", new File(result));// 输出到文件流 } } catch (IOException e) { e.printStackTrace(); } } /** * 缩放图像(按比例缩放) * * @param srcImageFile * 源图像文件地址 * @param result * 缩放后的图像地址 * @param scale * 缩放比例 * @param flag * 缩放选择:true 放大; false 缩小; */ public final static void scale(String srcImageFile, String result, int scale, boolean flag, int wd, int he) { try { synchronized (ImageUtils.class) { BufferedImage src = ImageIO.read(new File(srcImageFile)); // 读入文件 int width = src.getWidth(); // 得到源图宽 int height = src.getHeight(); // 得到源图长 if (flag) {// 放大 width = width * scale; height = height * scale; } else {// 缩小 int wScale = width / wd; int hScale = height / he; scale = wScale > hScale ? hScale : wScale; scale = scale < 1 ? 1 : scale; width = width / scale; height = height / scale; } Image image = src.getScaledInstance(width, height, Image.SCALE_DEFAULT); BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(image, 0, 0, null); // 绘制缩小后的图 g.dispose(); ImageIO.write(tag, "JPEG", new File(result));// 输出到文件流 } } catch (IOException e) { e.printStackTrace(); } } /** * 缩放图像(按比例缩放) * * @param srcImageFile * 源图像文件地址 * @param result * 缩放后的图像地址 * @param scale * 缩放比例t * @param flag * 缩放选择:true 放大; false 缩小; */ public final static void scaleByHeightAndWidth(int hightVal, int widthVal, String srcImageFile, String result, int scale, boolean flag) { try { synchronized (ImageUtils.class) { BufferedImage src = ImageIO.read(new File(srcImageFile)); // 读入文件 int width = src.getWidth(); // 得到源图宽 int height = src.getHeight(); // 得到源图长 if (flag) {// 放大 width = width * scale; height = height * scale; } else {// 缩小 int wScale = width / widthVal; int hScale = height / hightVal; scale = wScale > hScale ? hScale : wScale; scale = scale < 1 ? 1 : scale; width = width / scale; height = height / scale; } Image image = src.getScaledInstance(width, height, Image.SCALE_DEFAULT); BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(image, 0, 0, null); // 绘制缩小后的图 g.dispose(); ImageIO.write(tag, "JPEG", new File(result));// 输出到文件流 } } catch (IOException e) { e.printStackTrace(); } } /** * 缩放图像(按高度和宽度缩放) * * @param srcImageFile * 源图像文件地址 * @param result * 缩放后的图像地址 * @param height * 缩放后的高度 * @param width * 缩放后的宽度 * @param bb * 比例不对时是否需要补白:true为补白; false为不补白; */ @SuppressWarnings("static-access") @Deprecated public final static void scale2(String srcImageFile, String result, int height, int width, boolean bb) { try { double ratio = 0.0; // 缩放比例 File f = new File(srcImageFile); BufferedImage bi = ImageIO.read(f); Image itemp = bi.getScaledInstance(width, height, bi.SCALE_SMOOTH); // 计算比例 if ((bi.getHeight() > height) || (bi.getWidth() > width)) { if (bi.getHeight() > bi.getWidth()) { ratio = (new Integer(height)).doubleValue() / bi.getHeight(); } else { ratio = (new Integer(width)).doubleValue() / bi.getWidth(); } AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio), null); itemp = op.filter(bi, null); } if (bb) {// 补白 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = image.createGraphics(); g.setColor(Color.white); g.fillRect(0, 0, width, height); if (width == itemp.getWidth(null)) g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null), itemp.getHeight(null), Color.white, null); else g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null), itemp.getHeight(null), Color.white, null); g.dispose(); itemp = image; } ImageIO.write((BufferedImage) itemp, "JPEG", new File(result)); } catch (IOException e) { e.printStackTrace(); } } /** * 缩放图像(按高度和宽度缩放)不裁剪 * * @param srcImageFile * 源图像文件地址 * @param result * 缩放后的图像地址 * @param height * 缩放后的高度 * @param width * 缩放后的宽度 * @param bb * 比例不对时是否需要补白:true为补白; false为不补白; */ @SuppressWarnings("static-access") @Deprecated public final static void scaleWithoutCut(String srcImageFile, String result, int height, int width, boolean bb) { try { File f = new File(srcImageFile); BufferedImage bi = ImageIO.read(f); int width1 = bi.getWidth(); // 得到源图宽 int height1 = bi.getHeight(); // 得到源图长 Image itemp = bi.getScaledInstance(width, height, bi.SCALE_SMOOTH);// 创建此图像的缩放版本。返回一个新的 // Image // 对象,默认情况下,该对象按指定的 // width // 和 // height // 呈现图像。即使已经完全加载了初始源图像,新的 // Image // 对象也可以被异步加载。 AffineTransformOp op = new AffineTransformOp( AffineTransform.getScaleInstance(height1 / height, width1 / width), null); itemp = op.filter(bi, null); ImageIO.write((BufferedImage) itemp, "JPEG", new File(result)); } catch (IOException e) { e.printStackTrace(); } } /** * 图像切割(按指定起点坐标和宽高切割) * * @param srcImageFile * 源图像地址 * @param result * 切片后的图像地址 * @param x * 目标切片起点坐标X * @param y * 目标切片起点坐标Y * @param width * 目标切片宽度 * @param height * 目标切片高度 */ public final static void cut(String srcImageFile, String result, int x, int y, int width, int height) { try { // 读取源图像 BufferedImage bi = ImageIO.read(new File(srcImageFile)); int srcWidth = bi.getHeight(); // 源图宽度 int srcHeight = bi.getWidth(); // 源图高度 if (srcWidth > 0 && srcHeight > 0) { Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT); // 四个参数分别为图像起点坐标和宽高 // 即: CropImageFilter(int x,int y,int width,int height) ImageFilter cropFilter = new CropImageFilter(x, y, width, height); Image img = Toolkit.getDefaultToolkit() .createImage(new FilteredImageSource(image.getSource(), cropFilter)); BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(img, 0, 0, width, height, null); // 绘制切割后的图 g.dispose(); // 输出为文件 ImageIO.write(tag, "JPEG", new File(result)); } } catch (Exception e) { e.printStackTrace(); } } /** * 图像切割(按指定起点坐标和宽高切割)无压缩 * * @param srcImageFile * 源图像地址 * @param result * 切片后的图像地址 * @param x * 目标切片起点坐标X * @param y * 目标切片起点坐标Y * @param width * 目标切片宽度 * @param height * 目标切片高度 */ public final static void cutWithoutScale(String srcImageFile, String result, int x, int y, int width, int height) { try { // 读取源图像 BufferedImage bi = ImageIO.read(new File(srcImageFile)); int srcWidth = bi.getHeight(); // 源图宽度 int srcHeight = bi.getWidth(); // 源图高度 if (srcWidth > 0 && srcHeight > 0) { Image image = bi.getSubimage(x, y, width, height); // 四个参数分别为图像起点坐标和宽高 // 即: CropImageFilter(int x,int y,int width,int height) ImageFilter cropFilter = new CropImageFilter(x, y, width, height); Image img = Toolkit.getDefaultToolkit() .createImage(new FilteredImageSource(image.getSource(), cropFilter)); BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(img, 0, 0, width, height, null); // 绘制切割后的图 g.dispose(); // 输出为文件 ImageIO.write(tag, "JPEG", new File(result)); } } catch (Exception e) { e.printStackTrace(); } } /** * 图像切割(指定切片的行数和列数) * * @param srcImageFile * 源图像地址 * @param descDir * 切片目标文件夹 * @param rows * 目标切片行数。默认2,必须是范围 [1, 20] 之内 * @param cols * 目标切片列数。默认2,必须是范围 [1, 20] 之内 */ public final static void cut2(String srcImageFile, String descDir, int rows, int cols) { try { if (rows <= 0 || rows > 20) rows = 2; // 切片行数 if (cols <= 0 || cols > 20) cols = 2; // 切片列数 // 读取源图像 BufferedImage bi = ImageIO.read(new File(srcImageFile)); int srcWidth = bi.getHeight(); // 源图宽度 int srcHeight = bi.getWidth(); // 源图高度 if (srcWidth > 0 && srcHeight > 0) { Image img; ImageFilter cropFilter; Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT); int destWidth = srcWidth; // 每张切片的宽度 int destHeight = srcHeight; // 每张切片的高度 // 计算切片的宽度和高度 if (srcWidth % cols == 0) { destWidth = srcWidth / cols; } else { destWidth = (int) Math.floor(srcWidth / cols) + 1; } if (srcHeight % rows == 0) { destHeight = srcHeight / rows; } else { destHeight = (int) Math.floor(srcWidth / rows) + 1; } // 循环建立切片 // 改进的想法:是否可用多线程加快切割速度 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { // 四个参数分别为图像起点坐标和宽高 // 即: CropImageFilter(int x,int y,int width,int height) cropFilter = new CropImageFilter(j * destWidth, i * destHeight, destWidth, destHeight); img = Toolkit.getDefaultToolkit() .createImage(new FilteredImageSource(image.getSource(), cropFilter)); BufferedImage tag = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(img, 0, 0, null); // 绘制缩小后的图 g.dispose(); // 输出为文件 ImageIO.write(tag, "JPEG", new File(descDir + "_r" + i + "_c" + j + ".jpg")); } } } } catch (Exception e) { e.printStackTrace(); } } /** * 图像切割(指定切片的宽度和高度) * * @param srcImageFile * 源图像地址 * @param descDir * 切片目标文件夹 * @param destWidth * 目标切片宽度。默认200 * @param destHeight * 目标切片高度。默认150 */ public final static void cut3(String srcImageFile, String descDir, int destWidth, int destHeight) { try { if (destWidth <= 0) destWidth = 200; // 切片宽度 if (destHeight <= 0) destHeight = 150; // 切片高度 // 读取源图像 BufferedImage bi = ImageIO.read(new File(srcImageFile)); int srcWidth = bi.getHeight(); // 源图宽度 int srcHeight = bi.getWidth(); // 源图高度 if (srcWidth > destWidth && srcHeight > destHeight) { Image img; ImageFilter cropFilter; Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT); int cols = 0; // 切片横向数量 int rows = 0; // 切片纵向数量 // 计算切片的横向和纵向数量 if (srcWidth % destWidth == 0) { cols = srcWidth / destWidth; } else { cols = (int) Math.floor(srcWidth / destWidth) + 1; } if (srcHeight % destHeight == 0) { rows = srcHeight / destHeight; } else { rows = (int) Math.floor(srcHeight / destHeight) + 1; } // 循环建立切片 // 改进的想法:是否可用多线程加快切割速度 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { // 四个参数分别为图像起点坐标和宽高 // 即: CropImageFilter(int x,int y,int width,int height) cropFilter = new CropImageFilter(j * destWidth, i * destHeight, destWidth, destHeight); img = Toolkit.getDefaultToolkit() .createImage(new FilteredImageSource(image.getSource(), cropFilter)); BufferedImage tag = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(img, 0, 0, null); // 绘制缩小后的图 g.dispose(); // 输出为文件 ImageIO.write(tag, "JPEG", new File(descDir + "_r" + i + "_c" + j + ".jpg")); } } } } catch (Exception e) { e.printStackTrace(); } } /** * 图像类型转换:GIF->JPG、GIF->PNG、PNG->JPG、PNG->GIF(X)、BMP->PNG * * @param srcImageFile * 源图像地址 * @param formatName * 包含格式非正式名称的 String:如JPG、JPEG、GIF等 * @param destImageFile * 目标图像地址 */ public final static void convert(String srcImageFile, String formatName, String destImageFile) { try { File f = new File(srcImageFile); f.canRead(); f.canWrite(); BufferedImage src = ImageIO.read(f); ImageIO.write(src, formatName, new File(destImageFile)); } catch (Exception e) { e.printStackTrace(); } } /** * 彩色转为黑白 * * @param srcImageFile * 源图像地址 * @param destImageFile * 目标图像地址 */ public final static void gray(String srcImageFile, String destImageFile) { try { BufferedImage src = ImageIO.read(new File(srcImageFile)); ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY); ColorConvertOp op = new ColorConvertOp(cs, null); src = op.filter(src, null); ImageIO.write(src, "JPEG", new File(destImageFile)); } catch (IOException e) { e.printStackTrace(); } } /** * 给图片添加文字水印 * * @param pressText * 水印文字 * @param srcImageFile * 源图像地址 * @param destImageFile * 目标图像地址 * @param fontName * 水印的字体名称 * @param fontStyle * 水印的字体样式 * @param color * 水印的字体颜色 * @param fontSize * 水印的字体大小 * @param x * 修正值 * @param y * 修正值 * @param alpha * 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字 */ public final static void pressText(String pressText, String srcImageFile, String destImageFile, String fontName, int fontStyle, Color color, int fontSize, int x, int y, float alpha) { try { File img = new File(srcImageFile); Image src = ImageIO.read(img); int width = src.getWidth(null); int height = src.getHeight(null); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = image.createGraphics(); g.drawImage(src, 0, 0, width, height, null); g.setColor(color); g.setFont(new Font(fontName, fontStyle, fontSize)); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); // 在指定坐标绘制水印文字 g.drawString(pressText, (width - (getLength(pressText) * fontSize)) / 2 + x, (height - fontSize) / 2 + y); g.dispose(); ImageIO.write((BufferedImage) image, "JPEG", new File(destImageFile));// 输出到文件流 } catch (Exception e) { e.printStackTrace(); } } /** * 给图片添加文字水印 * * @param pressText * 水印文字 * @param srcImageFile * 源图像地址 * @param destImageFile * 目标图像地址 * @param fontName * 字体名称 * @param fontStyle * 字体样式 * @param color * 字体颜色 * @param fontSize * 字体大小 * @param x * 修正值 * @param y * 修正值 * @param alpha * 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字 */ public final static void pressText2(String pressText, String srcImageFile, String destImageFile, String fontName, int fontStyle, Color color, int fontSize, int x, int y, float alpha) { try { File img = new File(srcImageFile); Image src = ImageIO.read(img); int width = src.getWidth(null); int height = src.getHeight(null); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = image.createGraphics(); g.drawImage(src, 0, 0, width, height, null); g.setColor(color); g.setFont(new Font(fontName, fontStyle, fontSize)); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); // 在指定坐标绘制水印文字 g.drawString(pressText, (width - (getLength(pressText) * fontSize)) / 2 + x, (height - fontSize) / 2 + y); g.dispose(); ImageIO.write((BufferedImage) image, "JPEG", new File(destImageFile)); } catch (Exception e) { e.printStackTrace(); } } /** * 给图片添加图片水印 * * @param pressImg * 水印图片 * @param srcImageFile * 源图像地址 * @param destImageFile * 目标图像地址 * @param x * 修正值。 默认在中间 * @param y * 修正值。 默认在中间 * @param alpha * 透明度:alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字 */ public final static void pressImage(String pressImg, String srcImageFile, String destImageFile, int x, int y, float alpha) { try { File img = new File(srcImageFile); Image src = ImageIO.read(img); int wideth = src.getWidth(null); int height = src.getHeight(null); BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = image.createGraphics(); g.drawImage(src, 0, 0, wideth, height, null); // 水印文件 Image src_biao = ImageIO.read(new File(pressImg)); int wideth_biao = src_biao.getWidth(null); int height_biao = src_biao.getHeight(null); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); g.drawImage(src_biao, (wideth - wideth_biao) / 2, (height - height_biao) / 2, wideth_biao, height_biao, null); // 水印文件结束 g.dispose(); ImageIO.write((BufferedImage) image, "JPEG", new File(destImageFile)); } catch (Exception e) { e.printStackTrace(); } } /** * 计算text的长度(一个中文算两个字符) * * @param text * @return */ public final static int getLength(String text) { int length = 0; for (int i = 0; i < text.length(); i++) { if (new String(text.charAt(i) + "").getBytes().length > 1) { length += 2; } else { length += 1; } } return length / 2; } /** * 缩放图像(按高度和宽度缩放) * * @param srcImageFile * 源图像文件地址 * @param result * 缩放后的图像地址 * @param height * 缩放后的高度 * @param width * 缩放后的宽度 */ public static void scale(String srcImageFile, String result, int maxWidth, int maxHeight) { // 原图片 File in = new File(srcImageFile); // 目的图片 File out = new File(result); // 将图像缩略到指定尺寸以内,不足指定尺寸的则不做任何处理 ScaleParameter scaleParam = new ScaleParameter(maxWidth, maxHeight); FileInputStream inStream = null; FileOutputStream outStream = null; WriteRender wr = null; try { inStream = new FileInputStream(in); outStream = new FileOutputStream(out); ImageRender rr = new ReadRender(inStream); ImageRender sr = new ScaleRender(rr, scaleParam); wr = new WriteRender(sr, outStream); // 执行图像处理 wr.render(); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭图片文件输入输出流 IOUtils.closeQuietly(inStream); IOUtils.closeQuietly(outStream); if (wr != null) { try { // 释放simpleImage的内部资源 wr.dispose(); } catch (SimpleImageException ignore) { ignore.printStackTrace(); } } } } /** * 程序入口:用于测试 * * @param args */ public static void main(String[] args) { // 缩略图 // ImageUtils.scale("/Users/dewly/Downloads/TB1.9IXIFXXXXadaXXX2jHzFXXX_220x220.jpg", // "/Users/dewly/Downloads/test00-118x118.jpg", 118, 118); // ImageUtils.scale("d:/temp/1.png", "d:/temp/1_200x200.png", 200, 200); // 图片颜色处理(黑白彩色转换) // ImageUtils.gray("e:/test/test.jpg", "e:/test/test2.jpg");// 测试OK // 方法一:按比例缩放(放大缩小) ImageUtils.scale("d:/temp/222.png", "d:/temp/222_111.png", 4, false);// 测试OK // 方法二:按高度和宽度缩放(放大缩小) // ImageUtils.scale2("d:/temp/1.png", "d:/temp/1_720x720.png", 720,720, // true);// 测试OK // 5-给图片添加文字水印: // 方法一: // ImageUtils.pressText("我是水印文字", "e:/test/g.jpg", "e:/test/g2.jpg", // "宋体", Font.BOLD, Color.white, 80, 0, 0, 0.5f);// 测试OK // 方法二: // ImageUtils.pressText2("我也是水印文字", "e:/test/g.jpg", "e:/test/g3.jpg", // "黑体", 36, Color.white, 80, 0, 0, 0.5f);// 测试OK } }



上述代码有些冗余代码,时间有限,没有清理。个人也是多方收集资料完成功能的,如果有侵权,请联系我删除。

你可能感兴趣的:(使用谷歌开源组件tesseract-OCR识别身份证,通过opencv处理图像后再进行识别(windows版本))