Как сделать цвет прозрачным в BufferedImage и сохранить как PNG

Я искал в Интернете для этого, но я не нашел никакой достойной помощи.

У меня есть BufferedImage, который я прочитал с помощью ImageIO. Теперь я хотел бы сделать определенный цвет в этом изображении прозрачным и сохранить изображение как PNG.

Я знаю, что я не могу просто «нарисовать» прозрачный цвет по очевидным причинам, поэтому я предполагаю, что мне нужен какой-то фильтр.

У кого-нибудь есть образец кода?

Я сделал это недавно, чтобы ответить на вопрос моего менеджера проекта.
Функция, трансформирующая серый в прозрачность:

private Image TransformGrayToTransparency(BufferedImage image) { ImageFilter filter = new RGBImageFilter() { public final int filterRGB(int x, int y, int rgb) { return (rgb << 8) & 0xFF000000; } }; ImageProducer ip = new FilteredImageSource(image.getSource(), filter); return Toolkit.getDefaultToolkit().createImage(ip); } 

Фактически, он действует на изображении на уровне серого, поэтому я просто копирую компонент RGB (один R) в альфа, отбрасывая другие, которые идентичны в моем случае.
Вы можете адаптировать его для фильтрации определенного цвета, например. с проверкой равенства или дальности и т. д.
Конечно, BufferedImage должен быть типа BufferedImage.TYPE_INT_ARGB.

Я не рассматриваю вопрос сохранения, поскольку это довольно тривиально, но я могу добавить эту страницу кода тоже.

[EDIT] Чтобы преобразовать изображение в BufferedImage:

 BufferedImage dest = new BufferedImage( imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = dest.createGraphics(); g2.drawImage(image, 0, 0, null); g2.dispose(); 

[EDIT 2] Я пришел после того, как Christoffer опубликовал свое полное решение, но вот мое, я показываю, как сделать ряд цветов прозрачным. Может быть улучшено, например. используя вместо этого компоненты HSB.

 import java.awt.*; import java.awt.image.BufferedImage; import java.awt.image.FilteredImageSource; import java.awt.image.ImageFilter; import java.awt.image.ImageProducer; import java.awt.image.RGBImageFilter; import java.io.*; import javax.imageio.ImageIO; public class AddTransparency { AddTransparency() throws IOException { String imagePath = "E:/Documents/images/"; File inFile = new File(imagePath, "map.png"); BufferedImage image = ImageIO.read(inFile); Image transpImg1 = TransformGrayToTransparency(image); BufferedImage resultImage1 = ImageToBufferedImage(transpImg1, image.getWidth(), image.getHeight()); File outFile1 = new File(imagePath, "map_with_transparency1.png"); ImageIO.write(resultImage1, "PNG", outFile1); Image transpImg2 = TransformColorToTransparency(image, new Color(0, 50, 77), new Color(200, 200, 255)); BufferedImage resultImage2 = ImageToBufferedImage(transpImg2, image.getWidth(), image.getHeight()); File outFile2 = new File(imagePath, "map_with_transparency2.png"); ImageIO.write(resultImage2, "PNG", outFile2); } private Image TransformGrayToTransparency(BufferedImage image) { ImageFilter filter = new RGBImageFilter() { public final int filterRGB(int x, int y, int rgb) { return (rgb << 8) & 0xFF000000; } }; ImageProducer ip = new FilteredImageSource(image.getSource(), filter); return Toolkit.getDefaultToolkit().createImage(ip); } private Image TransformColorToTransparency(BufferedImage image, Color c1, Color c2) { // Primitive test, just an example final int r1 = c1.getRed(); final int g1 = c1.getGreen(); final int b1 = c1.getBlue(); final int r2 = c2.getRed(); final int g2 = c2.getGreen(); final int b2 = c2.getBlue(); ImageFilter filter = new RGBImageFilter() { public final int filterRGB(int x, int y, int rgb) { int r = (rgb & 0xFF0000) >> 16; int g = (rgb & 0xFF00) >> 8; int b = rgb & 0xFF; if (r >= r1 && r <= r2 && g >= g1 && g <= g2 && b >= b1 && b <= b2) { // Set fully transparent but keep color return rgb & 0xFFFFFF; } return rgb; } }; ImageProducer ip = new FilteredImageSource(image.getSource(), filter); return Toolkit.getDefaultToolkit().createImage(ip); } private BufferedImage ImageToBufferedImage(Image image, int width, int height) { BufferedImage dest = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = dest.createGraphics(); g2.drawImage(image, 0, 0, null); g2.dispose(); return dest; } public static void main(String[] args) throws IOException { AddTransparency at = new AddTransparency(); } } 

Благодаря PhilLo здесь представлено полное решение моего демонстрационного приложения.

 public static void main(String[] args) throws Exception { File in = new File("C:\\Users\\Christoffer\\Desktop\\christoffer.jpg"); BufferedImage source = ImageIO.read(in); int color = source.getRGB(0, 0); Image image = makeColorTransparent(source, new Color(color)); BufferedImage transparent = imageToBufferedImage(image); File out = new File("C:\\Users\\Christoffer\\Desktop\\trans.PNG"); ImageIO.write(transparent, "PNG", out); } private static BufferedImage imageToBufferedImage(Image image) { BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = bufferedImage.createGraphics(); g2.drawImage(image, 0, 0, null); g2.dispose(); return bufferedImage; } public static Image makeColorTransparent(BufferedImage im, final Color color) { ImageFilter filter = new RGBImageFilter() { // the color we are looking for... Alpha bits are set to opaque public int markerRGB = color.getRGB() | 0xFF000000; public final int filterRGB(int x, int y, int rgb) { if ((rgb | 0xFF000000) == markerRGB) { // Mark the alpha bits as zero - transparent return 0x00FFFFFF & rgb; } else { // nothing to do return rgb; } } }; ImageProducer ip = new FilteredImageSource(im.getSource(), filter); return Toolkit.getDefaultToolkit().createImage(ip); } 
Давайте будем гением компьютера.