java - 使用 Graphics2D 绘制 TYPE_INT_ARGB_PRE 类型的 BufferedImage 时遇到问题

标签 java image graphics2d lottie

在我的程序中,我得到了预乘 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);
}

这是白色背景上源图像的渲染:

sampleImageRenderedElsewhere.jpg

这是渲染的帧 (renderedFrame.png):

renderedFrame.png

这是我使用上面的代码渲染它时的样子(canvasImage.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/

相关文章:

java - 在 PaintComponent() 方法中变量未更改

Java - 打开 JScrollPane,并将 JScrollBar 设置为右侧

Java 如何使用 Graphics2D 制作抗锯齿线?

java - 现有 REST API 的 Swagger 实现

java - 获取 LIMIT 子句中预期的错误非负整数值

java - Android Studio - 查找壁纸中最主要的颜色

java - Primefaces TreeTable - 无法实例化类

.NET 按钮的图像

c# - 在javascript中更改图像控件的大小

angularjs - 文件 :///path image from SD-Card not showing in ionic cordova