java - 使用 Graphics2D 绘制 TYPE_INT_ARGB_PRE 类型的 BufferedImage 时遇到问题
问题描述
在我的程序中,我得到了预乘 ARGB 格式的图像数据。我正在执行以下操作来创建 BufferedImage,将其绘制到画布上,然后将其渲染为 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
我DirectDataBufferInt
从 jogl 库中使用的第一种方法: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。所以我基本上是在混淆我的频道。我猜是因为他们使用 uint32 作为缓冲区,我应该意识到这一点?无论如何 - 问题解决了。感谢大家的帮助。
推荐阅读
- c++ - 初始化多维数组
- minio - 如何将minio配置为只允许匿名用户下载而不允许列出存储桶或对象
- java - /me/accounts facebook 图形请求的 GraphResponse 失败
- javascript - 如何在修改其副本时避免更新原始数组?
- reactjs - 如何仅在按钮单击时触发具有多个依赖项的 useEffect()
- c++ - CMake ToolChain 的常用工具
- java - 如何为 Java Executor 的 runnable 提供参数?
- javascript - 在javascript中(ajax成功)在富文本区域中显示数据?
- pyqt5 - How can I add Icons to a QListWidget
- sql - 计算预订系统中每个时段的预订数量