身份证敏感信息处理 图片添加蒙版

实现效果

需要的jar包 

<!-- https://mvnrepository.com/artifact/com.jhlabs/filters -->
        <dependency>
            <groupId>com.jhlabs</groupId>
            <artifactId>filters</artifactId>
            <version>2.0.235-1</version>
        </dependency>

调用 

public static void main(String[] args) {

        try {
            byte[] bytes = PDFbox.pdf2Jpg(new BASE64Decoder().decodeBuffer(GetImageStr("E:/workspace/fline_work/js/2.pdf")));
            String filterBytes = MyGaussianFilterUtil.getFilterBytes(bytes);
            FileUtil.decoderBase64File(filterBytes,"E:\\workspace\\fline_work\\js\\file\\"+UUID.randomUUID().toString()+".jpg");
//            System.out.println(filterBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
}

根据坐标裁剪图片

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Iterator;

/**
 * 更具坐标裁剪图片
 */
public class OperateImageUtils {


    // ===源图片路径名称如:c:\1.jpg
    private String srcpath;

    // ===剪切图片存放路径名称.如:c:\2.jpg
    private String subpath;

    // ===剪切点x坐标
    private int x;

    private int y;

    // ===剪切点宽度
    private int width;

    private int height;

    public OperateImageUtils() {

    }

    public OperateImageUtils(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    /**
     * 对图片裁剪,并把裁剪完蛋新图片保存 。
     */
    public void cut() throws IOException {

        InputStream is = null;
        ImageInputStream iis = null;

        try {
            // 读取图片文件
            is = new FileInputStream(srcpath);

        /*
        * 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader
        * 声称能够解码指定格式。 参数:formatName - 包含非正式格式名称 .
        *(例如 "jpeg" 或 "tiff")等 。
      */
            Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName("jpg");
            ImageReader reader = it.next();
            // 获取图片流
            iis = ImageIO.createImageInputStream(is);

        /*
        * <p>iis:读取源.true:只向前搜索 </p>.将它标记为 ‘只向前搜索'。
        * 此设置意味着包含在输入源中的图像将只按顺序读取,可能允许 reader
        * 避免缓存包含与以前已经读取的图像关联的数据的那些输入部分。
      */
            reader.setInput(iis, true);

        /*
        * <p>描述如何对流进行解码的类<p>.用于指定如何在输入时从 Java Image I/O
        * 框架的上下文中的流转换一幅图像或一组图像。用于特定图像格式的插件
        * 将从其 ImageReader 实现的 getDefaultReadParam 方法中返回
        * ImageReadParam 的实例。
      */
            ImageReadParam param = reader.getDefaultReadParam();

        /*
        * 图片裁剪区域。Rectangle 指定了坐标空间中的一个区域,通过 Rectangle 对象
        * 的左上顶点的坐标(x,y)、宽度和高度可以定义这个区域。
      */
            Rectangle rect = new Rectangle(x, y, width, height);


            // 提供一个 BufferedImage,将其用作解码像素数据的目标。
            param.setSourceRegion(rect);

        /*
        * 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象,并将
        * 它作为一个完整的 BufferedImage 返回。
         */
            BufferedImage bi = reader.read(0, param);

            // 保存新图片
            ImageIO.write(bi, "jpg", new File(subpath));
        } finally {
            if (is != null)
                is.close();
            if (iis != null)
                iis.close();
        }


    }

    /**
     * 对图片裁剪,并把裁剪完蛋新图片保存 。
     */
    public void cut(byte[] bytes,String subpath) throws IOException {

        InputStream is = null;
        ImageInputStream iis = null;

        try {
            // 读取图片文件
            is = byte2InputStream(bytes);

        /*
        * 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader
        * 声称能够解码指定格式。 参数:formatName - 包含非正式格式名称 .
        *(例如 "jpeg" 或 "tiff")等 。
      */
            Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName("jpg");
            ImageReader reader = it.next();
            // 获取图片流
            iis = ImageIO.createImageInputStream(is);

        /*
        * <p>iis:读取源.true:只向前搜索 </p>.将它标记为 ‘只向前搜索'。
        * 此设置意味着包含在输入源中的图像将只按顺序读取,可能允许 reader
        * 避免缓存包含与以前已经读取的图像关联的数据的那些输入部分。
      */
            reader.setInput(iis, true);

        /*
        * <p>描述如何对流进行解码的类<p>.用于指定如何在输入时从 Java Image I/O
        * 框架的上下文中的流转换一幅图像或一组图像。用于特定图像格式的插件
        * 将从其 ImageReader 实现的 getDefaultReadParam 方法中返回
        * ImageReadParam 的实例。
      */
            ImageReadParam param = reader.getDefaultReadParam();

        /*
        * 图片裁剪区域。Rectangle 指定了坐标空间中的一个区域,通过 Rectangle 对象
        * 的左上顶点的坐标(x,y)、宽度和高度可以定义这个区域。
      */
            Rectangle rect = new Rectangle(x, y, width, height);


            // 提供一个 BufferedImage,将其用作解码像素数据的目标。
            param.setSourceRegion(rect);

        /*
        * 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象,并将
        * 它作为一个完整的 BufferedImage 返回。
         */
            BufferedImage bi = reader.read(0, param);

            // 保存新图片
            ImageIO.write(bi, "jpg", new File(subpath));
        } finally {
            if (is != null)
                is.close();
            if (iis != null)
                iis.close();
        }
    }
    public static InputStream byte2InputStream(byte[] bytes) {
        return new ByteArrayInputStream(bytes);
    }
    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public String getSrcpath() {
        return srcpath;
    }

    public void setSrcpath(String srcpath) {
        this.srcpath = srcpath;
    }

    public String getSubpath() {
        return subpath;
    }

    public void setSubpath(String subpath) {
        this.subpath = subpath;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

图片添加高斯模糊


import com.jhlabs.image.PixelUtils;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Kernel;
import java.io.*;
import java.util.Hashtable;
import java.util.UUID;

/**
 * 给图片添加蒙版方法
 */
public class MyGaussianFilterUtil {

    public static int CLAMP_EDGES = 1;
    public static int WRAP_EDGES = 2;
    protected Kernel kernel;
    protected boolean alpha = false;
    protected boolean premultiplyAlpha = false;

    protected float radius;

    public MyGaussianFilterUtil() {
        this(2.0F);
    }

    public MyGaussianFilterUtil(float radius) {
        this.setRadius(radius);
    }

    public void setRadius(float radius) {
        this.radius = radius;
        this.kernel = makeKernel(radius);
    }

    public float getRadius() {
        return this.radius;
    }

    public BufferedImage filter(BufferedImage src, BufferedImage dst) {
        int width = src.getWidth();
        int height = src.getHeight();
        if (dst == null) {
            dst = this.createCompatibleDestImage(src, (ColorModel)null);
        }

        int[] inPixels = new int[width * height];
        int[] outPixels = new int[width * height];
        src.getRGB(0, 0, width, height, inPixels, 0, width);
        if (this.radius > 0.0F) {
            //这里是对图片进行处理
            convolveAndTranspose(this.kernel, inPixels, outPixels, width, height, this.alpha, this.alpha && this.premultiplyAlpha, false, CLAMP_EDGES, 1);
            convolveAndTranspose(this.kernel, outPixels, inPixels, height, width, this.alpha, false, this.alpha && this.premultiplyAlpha, CLAMP_EDGES, 2);
        }

        dst.setRGB(0, 0, width, height, inPixels, 0, width);
        return dst;
    }

    public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
        if (dstCM == null) {
            dstCM = src.getColorModel();
        }

        return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dstCM.isAlphaPremultiplied(), (Hashtable)null);
    }

    public static Kernel makeKernel(float radius) {
        int r = (int)Math.ceil((double)radius);
        int rows = r * 2 + 1;
        float[] matrix = new float[rows];
        float sigma = radius / 3.0F;
        float sigma22 = 2.0F * sigma * sigma;
        float sigmaPi2 = 6.2831855F * sigma;
        float sqrtSigmaPi2 = (float)Math.sqrt((double)sigmaPi2);
        float radius2 = radius * radius;
        float total = 0.0F;
        int index = 0;

        int i;
        for(i = -r; i <= r; ++i) {
            float distance = (float)(i * i);
            if (distance > radius2) {
                matrix[index] = 0.0F;
            } else {
                matrix[index] = (float)Math.exp((double)(-distance / sigma22)) / sqrtSigmaPi2;
            }

            total += matrix[index];
            ++index;
        }

        for(i = 0; i < rows; ++i) {
            matrix[i] /= total;
        }

        return new Kernel(rows, 1, matrix);
    }

    public static void convolveAndTranspose(Kernel kernel, int[] inPixels, int[] outPixels, int width, int height, boolean alpha, boolean premultiply, boolean unpremultiply, int edgeAction,
                                            int type) {
        float[] matrix = kernel.getKernelData((float[])null);
        int cols = kernel.getWidth();
        int cols2 = cols / 2;

        int y = 0;
        //这里的height相当于要模糊图片的width(x轴),默认从0开始,我们修改这里的开始值,就能定义模糊位置
        if (type == 2) {
            y = height/3;
        }

        for(; y < height; ++y) {
            int index = y;
            int ioffset = y * width;

            for(int x = 0; x < width; ++x) {
                float r = 0.0F;
                float g = 0.0F;
                float b = 0.0F;
                float a = 0.0F;
                int moffset = cols2;

                int ia;
                int ix;
                int rgb;
                for(ia = -cols2; ia <= cols2; ++ia) {
                    float f = matrix[moffset + ia];
                    if (f != 0.0F) {
                        ix = x + ia;
                        if (ix < 0) {
                            if (edgeAction == CLAMP_EDGES) {
                                ix = 0;
                            } else if (edgeAction == WRAP_EDGES) {
                                ix = (x + width) % width;
                            }
                        } else if (ix >= width) {
                            if (edgeAction == CLAMP_EDGES) {
                                ix = width - 1;
                            } else if (edgeAction == WRAP_EDGES) {
                                ix = (x + width) % width;
                            }
                        }

                        rgb = inPixels[ioffset + ix];
                        int pa = rgb >> 24 & 255;
                        int pr = rgb >> 16 & 255;
                        int pg = rgb >> 8 & 255;
                        int pb = rgb & 255;
                        if (premultiply) {
                            float a255 = (float)pa * 0.003921569F;
                            pr = (int)((float)pr * a255);
                            pg = (int)((float)pg * a255);
                            pb = (int)((float)pb * a255);
                        }

                        a += f * (float)pa;
                        r += f * (float)pr;
                        g += f * (float)pg;
                        b += f * (float)pb;
                    }
                }

                if (unpremultiply && a != 0.0F && a != 255.0F) {
                    float f = 255.0F / a;
                    r *= f;
                    g *= f;
                    b *= f;
                }

                ia = alpha ? PixelUtils.clamp((int)((double)a + 0.5D)) : 255;
                int ir = PixelUtils.clamp((int)((double)r + 0.5D));
                ix = PixelUtils.clamp((int)((double)g + 0.5D));
                rgb = PixelUtils.clamp((int)((double)b + 0.5D));
                outPixels[index] = ia << 24 | ir << 16 | ix << 8 | rgb;
                index += height;
            }
        }

    }

    public static void  filter(String path,String savepath){
        try {
            MyGaussianFilterUtil gaussianFilter = new MyGaussianFilterUtil();
            BufferedImage fromImage = ImageIO.read(new File(path));
            BufferedImage toImage = new BufferedImage(fromImage.getWidth(), fromImage.getHeight(),BufferedImage.TYPE_INT_RGB);
            gaussianFilter.setRadius(40);
            gaussianFilter.filter(fromImage, toImage);
            ImageIO.write(toImage, "jpg", new File(savepath));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 递归删除目录下的所有文件及子目录下所有文件
     * @param dir 将要删除的文件目录
     * @return boolean Returns "true" if all deletions were successful.
     *                 If a deletion fails, the method stops attempting to
     *                 delete and returns "false".
     */
    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            for (int i=0; i<children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空,可以删除
        return dir.delete();
    }

    public static String getImageEncode(String imgPath,String filePath) {// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
        String imgFile = imgPath;// 待处理的图片
        InputStream in = null;
        byte[] data = null;
        String encode = null; // 返回Base64编码过的字节数组字符串
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        try {
            // 读取图片字节数组
            in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);
            encode = encoder.encode(data);
    } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        deleteDir(new File(filePath));
        return encode;
    }

    public static String getFilterBytes(byte[] bytes){
        try {
            String filePath = System.getProperty("user.dir") + File.separator + "tempfile"+ File.separator + UUID.randomUUID().toString()+File.separator;
            File file = new File(filePath);
            if(!file.exists()){
                file.mkdirs();
            }
            //截取图片
            OperateImageUtils operateImage = new OperateImageUtils(325, 390, 540, 745);
            String subPath = filePath+ UUID.randomUUID().toString()+".jpg";
            operateImage.cut(bytes,subPath);
            //给图片添加蒙版
            String savepath =filePath+ UUID.randomUUID().toString()+".jpg";
            MyGaussianFilterUtil.filter(subPath,savepath);
            //合并图片
            String bigPath = filePath+ UUID.randomUUID().toString()+".jpg";
            MergeImageUtil.mergeImage(bytes,bigPath,savepath,"325","390");
            return getImageEncode(bigPath,filePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

根据坐标合并图片

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

/**
 * 合并图片
 */
public class MergeImageUtil {
    /**
     *
     * @param bigPath 需要进行合并的大图
     * @param smallPath 需要进行合并的小图
     * @param x 坐标
     * @param y 坐标
     * @throws IOException
     */
    public static void mergeImage(String bigPath, String smallPath, String x, String y) throws IOException {

        try {
            BufferedImage small;
            BufferedImage big = ImageIO.read(new File(bigPath));
            if (smallPath.contains("http")) {

                URL url = new URL(smallPath);
                small = ImageIO.read(url);
            } else {
                small = ImageIO.read(new File(smallPath));
            }

            Graphics2D g = big.createGraphics();

            float fx = Float.parseFloat(x);
            float fy = Float.parseFloat(y);
            int x_i = (int) fx;
            int y_i = (int) fy;
            g.drawImage(small, x_i, y_i, small.getWidth(), small.getHeight(), null);
            g.dispose();
            ImageIO.write(big, "jpg", new File(bigPath));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param bytes 数据源
     * @param bigPath 需要进行合并的大图
     * @param smallPath 需要进行合并的小图
     * @param x 坐标
     * @param y 坐标
     * @throws IOException
     */
    public static void mergeImage(byte[] bytes,String bigPath, String smallPath, String x, String y) throws IOException {

        try {
            BufferedImage small;
            BufferedImage big = ImageIO.read(byte2InputStream(bytes));
            if (smallPath.contains("http")) {

                URL url = new URL(smallPath);
                small = ImageIO.read(url);
            } else {
                small = ImageIO.read(new File(smallPath));
            }

            Graphics2D g = big.createGraphics();

            float fx = Float.parseFloat(x);
            float fy = Float.parseFloat(y);
            int x_i = (int) fx;
            int y_i = (int) fy;
            g.drawImage(small, x_i, y_i, small.getWidth(), small.getHeight(), null);
            g.dispose();
            ImageIO.write(big, "jpg", new File(bigPath));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static InputStream byte2InputStream(byte[] bytes) {
        return new ByteArrayInputStream(bytes);
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

古月_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值