Возникли проблемы при рисовании BufferedImage типа TYPE_INT_ARGB_PRE с Graphics2D - PullRequest
1 голос
/ 27 октября 2019

В моей программе мне даны данные изображения в предварительно умноженном формате 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);
}

Вот рендер исходного изображения на белом фоне:

sampleImageRenderedElsewhere.jpg

Вот обработанный кадр (renderedFrame.png):

renderedFrame.png

И вот как это выглядит, когда я отрисовываю его с помощью приведенного выше кода (canvasImage.png):

canvasImage.png

Они выглядят одинаково, но это не так. canvasImage.png имеет белый фон, а renderedFrame.png прозрачный.

1 Ответ

1 голос
/ 28 октября 2019

Так что это мой плохой. Так как я никогда не проверял входящий формат, я отправил себя в погоню за гусем. По сути, документы Rlottie говорят ARGB32_Premultiplied формат. Но байты хранятся (в порядке появления): BGRA. Так что я в основном путал свои каналы. Я думаю, потому что они используют uint32 для буфера, я должен был это понять? В любом случае - проблема решена. Спасибо всем за помощь.

...