图片背景透明处理

时间:2022-10-24 00:03:58

图片背景透明处理图片背景透明处理













package com.dt.image;





import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.awt.image.*;
import java.awt.geom.AffineTransform;
import java.awt.color.ColorSpace;
import java.awt.image.ColorModel;
import java.awt.image.ConvolveOp;
import java.awt.image.DirectColorModel;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.Kernel;
import java.awt.image.BufferedImage;
import java.awt.image.RGBImageFilter;


import javax.imageio.ImageIO;


import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.Image;
import java.awt.Transparency;


//部分代码是从别人验证码识别工具中提取的
//只提取了图片预处理这一部分
//出自哪里我不知道了,资料找到太多了。
public class PicTouMing {
BufferedImage image;
private int iw, ih;
private int[] pixels;


public PicTouMing(BufferedImage image) {
this.image = image;
iw = image.getWidth();
ih = image.getHeight();
pixels = new int[iw * ih];


}


/** 图像二值化 */
public BufferedImage changeGrey() {


PixelGrabber pg = new PixelGrabber(image.getSource(), 0, 0, iw, ih,
pixels, 0, iw);
try {
pg.grabPixels();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 设定二值化的域值,默认值为100
int grey = 100;
// 对图像进行二值化处理,Alpha值保持不变
ColorModel cm = ColorModel.getRGBdefault();
for (int i = 0; i < iw * ih; i++) {
int red, green, blue;
int alpha = cm.getAlpha(pixels[i]);
if (cm.getRed(pixels[i]) > grey) {
red = 255;
} else {
red = 0;
}
if (cm.getGreen(pixels[i]) > grey) {
green = 255;
} else {
green = 0;
}
if (cm.getBlue(pixels[i]) > grey) {
blue = 255;
} else {
blue = 0;
}
pixels[i] = alpha << 24 | red << 16 | green << 8 | blue; // 通过移位重新构成某一点像素的RGB值
}
// 将数组中的象素产生一个图像
Image tempImg = Toolkit.getDefaultToolkit().createImage(
new MemoryImageSource(iw, ih, pixels, 0, iw));
image = new BufferedImage(tempImg.getWidth(null),
tempImg.getHeight(null), BufferedImage.TYPE_INT_BGR);
image.createGraphics().drawImage(tempImg, 0, 0, null);
return image;


}


/** 中值滤波 */
public BufferedImage getMedian() {
PixelGrabber pg = new PixelGrabber(image.getSource(), 0, 0, iw, ih,
pixels, 0, iw);
try {
pg.grabPixels();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 对图像进行中值滤波,Alpha值保持不变
ColorModel cm = ColorModel.getRGBdefault();
for (int i = 1; i < ih - 1; i++) {
for (int j = 1; j < iw - 1; j++) {
int red, green, blue;
int alpha = cm.getAlpha(pixels[i * iw + j]);


// int red2 = cm.getRed(pixels[(i - 1) * iw + j]);
int red4 = cm.getRed(pixels[i * iw + j - 1]);
int red5 = cm.getRed(pixels[i * iw + j]);
int red6 = cm.getRed(pixels[i * iw + j + 1]);
// int red8 = cm.getRed(pixels[(i + 1) * iw + j]);


// 水平方向进行中值滤波
if (red4 >= red5) {
if (red5 >= red6) {
red = red5;
} else {
if (red4 >= red6) {
red = red6;
} else {
red = red4;
}
}
} else {
if (red4 > red6) {
red = red4;
} else {
if (red5 > red6) {
red = red6;
} else {
red = red5;
}
}
}


int green4 = cm.getGreen(pixels[i * iw + j - 1]);
int green5 = cm.getGreen(pixels[i * iw + j]);
int green6 = cm.getGreen(pixels[i * iw + j + 1]);


// 水平方向进行中值滤波
if (green4 >= green5) {
if (green5 >= green6) {
green = green5;
} else {
if (green4 >= green6) {
green = green6;
} else {
green = green4;
}
}
} else {
if (green4 > green6) {
green = green4;
} else {
if (green5 > green6) {
green = green6;
} else {
green = green5;
}
}
}


// int blue2 = cm.getBlue(pixels[(i - 1) * iw + j]);
int blue4 = cm.getBlue(pixels[i * iw + j - 1]);
int blue5 = cm.getBlue(pixels[i * iw + j]);
int blue6 = cm.getBlue(pixels[i * iw + j + 1]);
// int blue8 = cm.getBlue(pixels[(i + 1) * iw + j]);


// 水平方向进行中值滤波
if (blue4 >= blue5) {
if (blue5 >= blue6) {
blue = blue5;
} else {
if (blue4 >= blue6) {
blue = blue6;
} else {
blue = blue4;
}
}
} else {
if (blue4 > blue6) {
blue = blue4;
} else {
if (blue5 > blue6) {
blue = blue6;
} else {
blue = blue5;
}
}
}
pixels[i * iw + j] = alpha << 24 | red << 16 | green << 8
| blue;
}
}


// 将数组中的象素产生一个图像
Image tempImg = Toolkit.getDefaultToolkit().createImage(
new MemoryImageSource(iw, ih, pixels, 0, iw));
image = new BufferedImage(tempImg.getWidth(null),
tempImg.getHeight(null), BufferedImage.TYPE_INT_BGR);
image.createGraphics().drawImage(tempImg, 0, 0, null);
return image;


}


public BufferedImage getGrey() {
ColorConvertOp ccp = new ColorConvertOp(
ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
return image = ccp.filter(image, null);
}


// Brighten using a linear formula that increases all color values
public BufferedImage getBrighten() {
RescaleOp rop = new RescaleOp(1.25f, 0, null);
return image = rop.filter(image, null);
}


// Blur by "convolving" the image with a matrix
public BufferedImage getBlur() {
float[] data = { .1111f, .1111f, .1111f, .1111f, .1111f, .1111f,
.1111f, .1111f, .1111f, };
ConvolveOp cop = new ConvolveOp(new Kernel(3, 3, data));
return image = cop.filter(image, null);


}


// Sharpen by using a different matrix
public BufferedImage getSharpen() {
float[] data = { 0.0f, -0.75f, 0.0f, -0.75f, 4.0f, -0.75f, 0.0f,
-0.75f, 0.0f };
ConvolveOp cop = new ConvolveOp(new Kernel(3, 3, data));
return image = cop.filter(image, null);
}


// 11) Rotate the image 180 degrees about its center point
public BufferedImage getRotate() {
AffineTransformOp atop = new AffineTransformOp(
AffineTransform.getRotateInstance(Math.PI,
image.getWidth() / 2, image.getHeight() / 2),
AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
return image = atop.filter(image, null);
}


public BufferedImage getProcessedImg() {
return image;
}


public static String KaiCao(String strpath) throws IOException {
// String[] argz={strpath};
// 图片像素太大了,会有异常
System.out.println("strPath:" + strpath);


FileInputStream fin = new FileInputStream(strpath);
BufferedImage bi = ImageIO.read(fin);
PicTouMing flt = new PicTouMing(bi);
flt.changeGrey();
flt.getGrey();
flt.getBrighten();
bi = flt.getProcessedImg();
// 这部分代码,之前是返回一个image对象,image对象是不能直接保存为图像文件的,
// 害得我昨天搞了一下午,原因在于图片处理这一块不熟悉
String pname = strpath.substring(0, strpath.lastIndexOf("."));
File file = new File(pname + "-ok.png");
ImageIO.write(bi, "png", file);
System.out.println("filePath:" + file.toString());
return file.toString();
}


public static String KaiCao2(String imgPath) {


// 被修改图片
// String imgPath = "C:\\zhangll\\picTest\\063.gif";
// 处理后,保存的路径
String imgPathOut = imgPath.substring(0, imgPath.lastIndexOf("."))
+ "-TM.png";
try {
BufferedImage image = ImageIO.read(new FileInputStream(imgPath));


// new一张一样大的图,用于存放修改后的图
int width = image.getWidth();// 宽
int height = image.getHeight();// 高
// 创建一个image容器,用于存放处理后的image
BufferedImage images = PicTouMing
.TouMingPic(width, height, 0, null);


Graphics2D g = images.createGraphics();
// 将白色透明处理
ImageFilter imgf = new PicTouMings(255);
FilteredImageSource fis = new FilteredImageSource(
image.getSource(), imgf);
Image im = Toolkit.getDefaultToolkit().createImage(fis);
g.drawImage(im, 0, 0, width, height, null);
g.dispose();
// 透明图片可以保存为png格式或者gif格式
File file = new File(imgPathOut);
ImageIO.write(images, "png", file);
System.out.println("---ok:" + file.toString());
return file.toString();


} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}


public static BufferedImage TouMingPic(int width, int height, int issave,
String path) {
// 创建一个可以保存的image
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
image = g2d.getDeviceConfiguration().createCompatibleImage(width,
height, Transparency.TRANSLUCENT);
g2d.dispose();
g2d = image.createGraphics();
g2d.setStroke(new BasicStroke(1));
// 释放对象
g2d.dispose();
// 保存文件
if (issave == 1) {


try {


SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");// 设置日期格式
String dxx = df.format(new Date());
// 另存为图片 即修改后图片
String imgPathOut = path + dxx + ".png";
ImageIO.write(image, "png", new File(imgPathOut));
System.out.println("透明ok:" + imgPathOut);
} catch (IOException e) {
e.printStackTrace();
}
}
return image;
}


public static void main(String[] args) throws IOException {
// i为有几张图,从0开始
// for (int i = 0; i < 43; i++) {
// String strpath = "C:\\zhangll\\picTest\\q\\H-" + i + ".png";
// MyImgFilter.KaiCao(strpath);
// }
//String strpath = "./jb.jpg";
String strpath="F:\\image\\1.png";
String kaicao = PicTouMing.KaiCao(strpath);
System.out.println("预处理完成,使用PS或者别的图形处理软件,擦除掉不能自动处理的多余部分");
String kaicao2 = PicTouMing.KaiCao2(kaicao);
System.out.println("透明处理完成");


}


}


class PicTouMings extends RGBImageFilter {
int alpha = 0;


public PicTouMings(int alpha) {
// 用来接收需要过滤图象的尺寸,以及透明度
this.canFilterIndexColorModel = true;
this.alpha = alpha;
}


public int filterRGB(int x, int y, int rgb) {
DirectColorModel dcm = (DirectColorModel) ColorModel.getRGBdefault();
int red = dcm.getRed(rgb);
int green = dcm.getGreen(rgb);
int blue = dcm.getBlue(rgb);
int alp = dcm.getAlpha(rgb);
// 指定颜色替换为透明
if (red == 255 && blue == 255 && green == 255) {
// 如果像素为白色,则让它透明
alpha = 0;
} else {
alpha = 255;
}
// if (alp == 0) {
// // png和gif格式图片透明部分仍然透明
// alpha = 0;
// } else {
// alpha = 255;
// }
return alpha << 24 | red << 16 | green << 8 | blue;
}


}