java图像合并之身份证正反面合成图片

转载 2020-03-26 13:46 Java 29

操作步骤

先从百度图片里面,下载两张图片,一张身份证正面,一张身份证反面

然后运行代码,即可获得一张正反面的身份证图片

举个栗子:

这是 正面

Java图像合并之身份证正反面合成图片

这是反面

Java图像合并之身份证正反面合成图片

合成的结果图:

Java图像合并之身份证正反面合成图片
java 复制代码
package com.example.demo.utils;

import org.apache.commons.codec.binary.Base64;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageOutputStream;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.*;

public class ImageMergeUtil {

    private static Logger LOGGER = LogManager.getLogger(ImageMergeUtil.class);

    /**
     * 图像合并bytes [图片类型]
     *
     * @param prosPath 第一张图片路径
     * @param consPath 第二张图片路径
     * @return
     */
    public static byte[] imageMergeToBytes(String prosPath, String consPath) throws IOException {
        LOGGER.info("prosFile:" + prosPath + ";consFile:" + consPath);
        byte[] bytes;
        // 读取待合并的文件
        BufferedImage prosImg = null;
        prosImg = ImageIO.read(new File(prosPath));
        BufferedImage consImg = ImageIO.read(new File(consPath));
        // 图像压缩
        prosImg = resize(prosImg, 1000, 1000, true);
        consImg = resize(consImg, 1000, 1000, true);
        // 合并后图像
        BufferedImage mergeImg = mergeImage(prosImg, consImg, false);
        // 压缩 后大概100K-300K
        mergeImg = resize(mergeImg, 1000, 1000, false);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(mergeImg, "jpg", baos);
        bytes = baos.toByteArray();
        baos.close();
        return bytes;
    }

    /**
     * 图像合并bytes [.dat类型]
     *
     * @param prosPath 第一张图片路径
     * @param consPath 第二张图片路径
     * @return
     */
    public static byte[] imageMergeToBytes2(String prosPath, String consPath) throws IOException {
        LOGGER.info("prosPath:" + prosPath + ";consPath:" + consPath);
        // 读取待合并的文件
        BufferedImage bi1 = null;
        BufferedImage bi2 = null;
        // 调用mergeImage方法获得合并后的图像
        BufferedImage destImg = null;
        String imgStr = "";
        byte[] bytes = null;
        // 读取图片的base64String
        String prosString = readFile2String(prosPath, "");
        String consString = readFile2String(consPath, "");
        bi1 = getBufferedImage(prosString);
        bi1 = resize(bi1, 1000, 1000, true);
        bi2 = getBufferedImage(consString);
        bi2 = resize(bi2, 1000, 1000, true);
        // 合成
        destImg = mergeImage(bi1, bi2, false);
        // 压缩 后大概100K-300K
        destImg = resize(destImg, 1000, 1000, false);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(destImg, "jpg", baos);
        bytes = baos.toByteArray();
        return bytes;
    }

    /**
     * @param base64string 图片base64编码
     * @return 读取到的缓存图像
     * @throws IOException 路径错误或者不存在该文件时抛出IO异常
     */
    private static BufferedImage getBufferedImage(String base64string) throws IOException {
        InputStream stream = BaseToInputStream(base64string);
        return ImageIO.read(stream);
    }

    private static InputStream BaseToInputStream(String base64string) throws IOException {
        ByteArrayInputStream stream = null;
        byte[] bytes1 = Base64.decodeBase64(base64string.getBytes());
        stream = new ByteArrayInputStream(bytes1);
        return stream;
    }

    /**
     * @param fileName
     * @param encoding 编码类型
     * @return 转换后的字符串
     */
    public static String readFile2String(String fileName, String encoding) {
        InputStreamReader reader = null;
        StringWriter writer = new StringWriter();
        try {
            File file = new File(fileName);
            if (encoding != null && !"".equals(encoding.trim())) {
                reader = new InputStreamReader(new FileInputStream(file), encoding);
            } else {
                reader = new InputStreamReader(new FileInputStream(file));
            }
            char[] buffer = new char[8 * 1024];
            int n = 0;
            while (-1 != (n = reader.read(buffer))) {
                writer.write(buffer, 0, n);
            }
            reader.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (writer != null) {
                try {
                    writer.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        if (writer != null) {
            return writer.toString();
        } else {
            return null;
        }
    }

    /**
     * 免冠照
     *
     * @return
     */
    public static byte[] mgImage(String path) throws IOException {
        LOGGER.info("path:" + path);
        byte[] bytes;
        // 读取待合并的文件
        BufferedImage mgImg = ImageIO.read(new File(path));
        // 图像压缩
        mgImg = resize(mgImg, 1000, 1000, true);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(mgImg, "jpg", baos);
        bytes = baos.toByteArray();
        baos.close();
        return bytes;
    }

    /**
     * 获取免冠照
     *
     * @param mgImage
     * @return
     */
    public static String mgImageToString(String mgImage) throws IOException {
        byte[] bytes = mgImage(mgImage);
        return Base64.encodeBase64String(bytes);
    }

    /**
     * 图像合并String [图片类型]
     *
     * @param prosPath 第一张图片路径
     * @param consPath 第二张图片路径
     * @return
     */
    public static String imageMergeToString(String prosPath, String consPath) throws IOException {
        byte[] bytes = imageMergeToBytes(prosPath, consPath);
        return Base64.encodeBase64String(bytes);
    }

    /**
     * 图像合并String [.dat类型]
     *
     * @param prosPath 第一张图片路径
     * @param consPath 第二张图片路径
     * @return
     */
    public static String imageMergeToString2(String prosPath, String consPath) throws IOException {
        byte[] bytes;
        bytes = imageMergeToBytes2(prosPath, consPath);
        return Base64.encodeBase64String(bytes);
    }

    /**
     * 压缩图片
     */
    private static BufferedImage resize(BufferedImage source, int targetW, int targetH, boolean isRotate) {
        // targetW,targetH分别表示目标长和宽
        int type = source.getType();
        BufferedImage target = null;
        int width = source.getWidth();
        int height = source.getHeight();
        // 图片宽度小于高度 需要 则调整 宽高 值
        if (width < height && isRotate) {
            width = height;
            height = source.getWidth();
        }
        double sx = (double) targetW / width;
        double sy = (double) targetH / height;
        // 这里想实现在targetW,targetH范围内实现等比缩放
        if (sx > sy) {
            sx = sy;
            targetW = (int) (sx * source.getWidth());
        } else {
            sy = sx;
            targetH = (int) (sy * source.getHeight());
        }
        if (type == BufferedImage.TYPE_CUSTOM) {
            ColorModel cm = source.getColorModel();
            WritableRaster raster = cm.createCompatibleWritableRaster(targetW, targetH);
            boolean alphaPremultiplied = cm.isAlphaPremultiplied();
            target = new BufferedImage(cm, raster, alphaPremultiplied, null);
        } else {
            target = new BufferedImage(targetW, targetH, type);
        }
        Graphics2D g = target.createGraphics();
        // smoother than exlax:
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));
        g.dispose();
        return target;
    }

    /**
     * 待合并的两张图必须满足这样的前提,如果水平方向合并,则高度必须相等;如果是垂直方向合并,宽度必须相等。
     * mergeImage方法不做判断,自己判断。
     *
     * @param img1         待合并的第一张图
     * @param img2         带合并的第二张图
     * @param isHorizontal 为true时表示水平方向合并,为false时表示垂直方向合并
     * @return 返回合并后的BufferedImage对象
     * @throws IOException
     */
    private static BufferedImage mergeImage(BufferedImage img1, BufferedImage img2, boolean isHorizontal) throws IOException {
        int w1 = img1.getWidth();
        int h1 = img1.getHeight();
        int w2 = img2.getWidth();
        int h2 = img2.getHeight();
        // 从图片中读取RGB
        int[] ImageArrayOne = new int[w1 * h1];
        // 逐行扫描图像中各个像素的RGB到数组中
        ImageArrayOne = img1.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1);
        int[] ImageArrayTwo = new int[w2 * h2];
        ImageArrayTwo = img2.getRGB(0, 0, w2, h2, ImageArrayTwo, 0, w2);
        // 生成新图片
        BufferedImage destImage = null;
        if (isHorizontal) {
            // 水平方向合并
            destImage = new BufferedImage(w1 + w2, h1, BufferedImage.TYPE_INT_RGB);
            // 设置上半部分或左半部分的RGB
            destImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1);
            destImage.setRGB(w1, 0, w2, h2, ImageArrayTwo, 0, w2);
        } else { // 垂直方向合并
            destImage = new BufferedImage(w1, h1 + h2, BufferedImage.TYPE_INT_RGB);
            // 设置上半部分或左半部分的RGB
            destImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1);
            // 设置下半部分的RGB
            destImage.setRGB(0, h1, w2, h2, ImageArrayTwo, 0, w2);
        }
        return destImage;
    }

    //byte数组到图片
    private static void byte2image(byte[] data, String path) {
        if (data.length < 3 || path.equals("")) {
            return;
        }
        try {
            FileImageOutputStream imageOutput = new FileImageOutputStream(new File(path));
            imageOutput.write(data, 0, data.length);
            imageOutput.close();
            System.out.println("Make Picture success,Please find image in " + path);
        } catch (Exception ex) {
            System.out.println("Exception: " + ex);
            ex.printStackTrace();
        }
    }
    
    public static void main(String[] args) throws Exception {
        byte[] imgStr = ImageMergeUtil.imageMergeToBytes("C:\\Users\\Administrator\\Desktop\\test2.jpg", "C:\\Users\\Administrator\\Desktop\\test3.jpg");
        System.out.println(imgStr.toString());
        ImageMergeUtil.byte2image(imgStr, "C:\\Users\\Administrator\\Desktop\\test4.jpg");
        System.out.println("成功……………………..");
    }

}
点赞
收藏
关注
转发
本文作者: Veddy
版权声明: 本博客所有文章除特别声明外,均采用 CC BY 4.0 CN协议进行许可。转载请署名作者且注明文章出处。
文章目录