Bootstrap

Java图片背景颜色变透明

Java图片背景颜色变透明

说明

话不多说,直接上工具类,类中提供了方法
noBackground() 对图片背景色是否透明进行判断。
imageToPng() 对图片背景色进行透明处理。

效果

处理前

在这里插入图片描述

处理后

在这里插入图片描述

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.io.*;

public class ImageTest {
    public static void main(String[] args) throws Exception{
        String inFilePath = "",outFilePath = "";
        inFilePath = "D:\\tmp\\images\\110.png";
        outFilePath = "D:\\tmp\\images\\1104.png";
        bufferWrite(imageToPng(new File(inFilePath)),outFilePath);
        System.out.println("ok");
    }

    /**
     *  图片设置透明背景颜色
     * @param imageBytes 原图
     * */
    public static byte[] imageToPng(byte [] imageBytes)throws Exception{
        ByteArrayInputStream bais = null;
        try{
            bais = new ByteArrayInputStream(imageBytes);
            return imageToPng(bais);
        }finally {
            FileUtil.closeStream(bais);
        }
    }

    /**
     *  图片设置透明背景颜色
     * @param file 原图
     * */
    public static byte[] imageToPng(File file)throws Exception{
        BufferedImage bufferedImage = ImageIO.read(file);
        return imageToPng(bufferedImage);
    }

    /**
     *  图片设置透明背景颜色
     * @param is 原图
     * */
    public static byte[] imageToPng(InputStream is)throws Exception{
        BufferedImage bufferedImage = ImageIO.read(is);
        return imageToPng(bufferedImage);
    }

    /**
     *  图片设置透明背景颜色
     * @param image 原图
     * */
    public static byte[] imageToPng(BufferedImage image)throws Exception{

        if(image==null)
            return null;
        ByteArrayOutputStream baos = null;
        byte [] bytes = null;

        if(noBackground(image)){
            /*背景透明时,直接返回原图*/
            baos = new ByteArrayOutputStream();
            ImageIO.write(image, "png", baos);
            bytes = baos.toByteArray();
            return bytes;
        }

        try {
            baos = new ByteArrayOutputStream();

            // 高度和宽度
            int height = image.getHeight();
            int width = image.getWidth();

            // 初始化背景透明和内容透明的图片
            ImageIcon imageIcon = new ImageIcon(image);
            BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
            Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics(); // 获取画笔
            // 绘制Image的图片
            g2D.drawImage(imageIcon.getImage(), 0, 0, null);

            int alpha = 0; // 图片透明度
            // 外层遍历是Y轴的像素
            for (int y = bufferedImage.getMinY(); y < bufferedImage.getHeight(); y++) {
                // 内层遍历是X轴的像素
                for (int x = bufferedImage.getMinX(); x < bufferedImage.getWidth(); x++) {
                    int rgb = bufferedImage.getRGB(x, y);
                    // 对当前颜色判断是否在指定区间内
                    if (colorInRange(rgb)){
                        alpha = 0;
                    }else{
                        // 设置为不透明
                        alpha = 255;
                    }
                    //最前两位为透明度
                    rgb = (alpha << 24) | (rgb & 0x00ffffff);
                    bufferedImage.setRGB(x, y, rgb);
                }
            }
            // 绘制设置了RGB的新图片,这一步感觉不用也可以,只是透明地方的深浅有变化而已,就像蒙了两层的感觉
            g2D.drawImage(bufferedImage, 0, 0, null);

            // 生成图片为PNG
            ImageIO.write(bufferedImage, "png", baos);
            bytes = baos.toByteArray();
        }finally {
            FileUtil.closeStream(baos);
        }
        return bytes;
    }

    //色差范围0~255
    public static int color_range = 210;
    // 判断是背景还是内容
    public static boolean colorInRange(int color) {
        int red = (color & 0xff0000) >> 16;// 获取color(RGB)中R位
        int green = (color & 0x00ff00) >> 8;// 获取color(RGB)中G位
        int blue = (color & 0x0000ff);// 获取color(RGB)中B位
        // 通过RGB三分量来判断当前颜色是否在指定的颜色区间内
        if (red >= color_range && green >= color_range && blue >= color_range){
            return true;
        };
        return false;
    }

    /**
     * 判断是否有背景颜色
     * @return
     *     true 无背景颜色;false 有背景颜色
     * */
    public static boolean noBackground(byte [] imageBytes)throws Exception{
        ByteArrayInputStream bais = null;
        try{
            bais = new ByteArrayInputStream(imageBytes);
            return noBackground(bais);
        }finally {
            FileUtil.closeStream(bais);
        }
    }

    /**
     * 判断是否有背景颜色
     * @return
     *     true 无背景颜色;false 有背景颜色
     * */
    public static boolean noBackground(InputStream is)throws Exception{
        BufferedImage bufferedImage = ImageIO.read(is);
        return noBackground(bufferedImage);
    }

    /**
     * 判断是否有背景颜色
     * @return
     *     true 无背景颜色;false 有背景颜色
     * */
    public static boolean noBackground(BufferedImage bufferedImage)throws Exception{
        if(bufferedImage ==null)
            return false;
        int height = bufferedImage.getHeight();
        int width = bufferedImage.getWidth();

        for(int w=0;w<width;w++){
            for(int h=0;h<height;h++){
                int rgb = bufferedImage.getRGB(w,h);
                if(rgb >> 24==0){
                    return true;
                }
            }
        }
        return false;
    }
    public static void bufferWrite(byte[] data,String filePath) throws Exception {
        FileOutputStream fos = null;
        try{
            fos = new FileOutputStream(filePath);
            fos.write(data);
        }finally{
            if(fos!=null)
                fos.close();
        }
    }
}
;