在 Java 中设置 BufferedImage alpha 掩码
2022-09-02 02:57:17
我有两个从pngs加载的缓冲图像。第一个包含图像,第二个包含图像的 Alpha 蒙版。
我想通过应用 Alpha 蒙版从两者创建一个组合图像。我的谷歌-fu让我失望了。
我知道如何加载/保存图像,我只需要从两个BufferedImages到一个具有正确alpha通道的BufferedImage的位。
我有两个从pngs加载的缓冲图像。第一个包含图像,第二个包含图像的 Alpha 蒙版。
我想通过应用 Alpha 蒙版从两者创建一个组合图像。我的谷歌-fu让我失望了。
我知道如何加载/保存图像,我只需要从两个BufferedImages到一个具有正确alpha通道的BufferedImage的位。
我对这个答案为时已晚,但也许它对某人有用。这是迈克尔·迈尔斯方法的更简单,更有效的版本:
public void applyGrayscaleMaskToAlpha(BufferedImage image, BufferedImage mask)
{
int width = image.getWidth();
int height = image.getHeight();
int[] imagePixels = image.getRGB(0, 0, width, height, null, 0, width);
int[] maskPixels = mask.getRGB(0, 0, width, height, null, 0, width);
for (int i = 0; i < imagePixels.length; i++)
{
int color = imagePixels[i] & 0x00ffffff; // Mask preexisting alpha
int alpha = maskPixels[i] << 24; // Shift blue to alpha
imagePixels[i] = color | alpha;
}
image.setRGB(0, 0, width, height, imagePixels, 0, width);
}
它在开始时将所有像素读入数组,因此只需要一个 for 循环。此外,它直接将蓝色字节移动到(蒙版颜色的 alpha),而不是先遮罩红色字节,然后再移动它。
与其他方法一样,它假设两个图像具有相同的尺寸。
我最近玩了一下这个东西,在另一个图像上显示一个图像,并将图像淡入灰色。
还要用具有透明度的遮罩遮罩图像(我此消息的先前版本!
我把我的小测试程序调整了一下,以获得想要的结果。
以下是相关位:
TestMask() throws IOException
{
m_images = new BufferedImage[3];
m_images[0] = ImageIO.read(new File("E:/Documents/images/map.png"));
m_images[1] = ImageIO.read(new File("E:/Documents/images/mapMask3.png"));
Image transpImg = TransformGrayToTransparency(m_images[1]);
m_images[2] = ApplyTransparency(m_images[0], transpImg);
}
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 BufferedImage ApplyTransparency(BufferedImage image, Image mask)
{
BufferedImage dest = new BufferedImage(
image.getWidth(), image.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = dest.createGraphics();
g2.drawImage(image, 0, 0, null);
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.DST_IN, 1.0F);
g2.setComposite(ac);
g2.drawImage(mask, 0, 0, null);
g2.dispose();
return dest;
}
其余的只是在一个小的Swing面板中显示图像。
请注意,蒙版图像是灰度级别的,黑色变为完全透明,白色变为完全不透明。
虽然你已经解决了你的问题,但我可以分享我对它的看法。它使用稍微更像Java的方法,使用标准类来处理/过滤图像。
实际上,我的方法使用更多的内存(制作额外的图像),我不确定它是否更快(测量各自的性能可能很有趣),但它稍微抽象一些。
至少,你有选择!:-)