说明
话不多说,直接上工具类,类中提供了方法
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();
}
}
}