在我的程序中,我得到了预乘 ARGB 格式的图像数据。我正在执行以下操作来创建 BufferedImage,将其绘制到 Canvas 上,然后将其渲染为 PNG 图像,但生成的图像颜色错误:
IntBuffer imageData = ....;
BufferedImage renderedFrame = createBufferedImage(surface.getWidth(), surface.getHeight(), imageData);
DataBufferInt rasterData = (DataBufferInt)renderedFrame.getData().getDataBuffer();
imageData.get(rasterData.getData());
ImageIO.write(renderedFrame, "PNG", new File("/tmp/renderedFrame.png")); // the image is rendered, but the colors are all off
final BufferedImage canvasImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
final Graphics2D g = canvasImage.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, surface.getWidth(), surface.getHeight());
g.setComposite(AlphaComposite.SrcOver);
g.drawImage(renderedFrame, 0, 0, width, height, null, null);
ImageIO.write(canvasImage, "PNG", new File("/tmp/canvasImage.png")); // the image is rendered, but the colors are all off
我已验证图像数据正确,它来自 rlottie ( https://github.com/Samsung/rlottie )。我只需要把它合成到另一个图像上。
对于第一个 createBufferedImage
方法,我使用 jogl 库中的 DirectDataBufferInt
:https://github.com/JogAmp/jogl/blob/master/src/nativewindow/classes/com/jogamp/nativewindow/awt/DirectDataBufferInt.java以便图像的 DataBuffer 由 NIO 缓冲区支持。以下是 createBufferedImage
方法的内容:
private BufferedImage createBufferedImage(int width, int height, ByteBuffer buffer) {
DirectDataBufferInt intBuffer = new DirectDataBufferInt(buffer, width * height);
return DirectDataBufferInt.createBufferedImage(width, height, intBuffer, BufferedImage.TYPE_INT_ARGB_PRE, null, null);
}
这是白色背景上源图像的渲染:
这是渲染的帧 (renderedFrame.png
):
这是我使用上面的代码渲染它时的样子(canvasImage.png
):
它们看起来一样,但其实不然。 canvasImage.png
具有白色背景,而 renderedFrame.png
是透明的。
最佳答案
所以这是我的错。由于我从未验证过传入的格式,所以我最终让自己陷入了徒劳的追逐之中。本质上,rlottie 文档说的是 ARGB32_Premultiplied 格式。但字节存储(按出现顺序):BGRA。所以我基本上是在混淆我的 channel 。我想因为他们使用 uint32 作为缓冲区我应该意识到这一点?不管怎样——问题解决了。感谢大家的帮助。
关于java - 使用 Graphics2D 绘制 TYPE_INT_ARGB_PRE 类型的 BufferedImage 时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58582075/