身份证识别
,前面有一篇已经介绍tesseract-OCR的简单实用和识别,因识别率不高,特意将图片实用opencv处理后,再次进行识别,经过测试,识别率高了30%左右
2,实用opcv整合tesseract-OCR需要的jar包,此处的识别已经不再通过调用windows系统命令,而通过tesseract-OCR工具类tess4j.jar完成。(实际上tess4j也是调用系统命令)
3,注意到上面有个opencv_java320.dll(32位和64位,根据你的jdk决定,到时我发现在这儿其实好像加载不到,所以使用一下方法)
将opencv_java320.dll加入到系统库的Native library location(如图)
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<String> cmd = new ArrayList<String>();
- 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;
- }
- /**
- * <p>
- * Title: cutImage
- * </p>
- * <p>
- * Description: 根据原图与裁切size截取局部图片
- * </p>
- *
- * @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;
- /**
- * 图片处理工具类:<br>
- * 功能:缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等
- *
- */
- 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
- }
- }

浙公网安备 33010602011771号