bytedeco/javacv

Bug in Java2DFrameConverter

Open

#1,075 opened on Oct 25, 2018

View on GitHub
 (1 comment) (0 reactions) (0 assignees)Java (1,583 forks)batch import
enhancementhelp wanted

Repository metrics

Stars
 (6,985 stars)
PR merge metrics
 (No merged PRs in 30d)

Description

Hi guys. Java2DFrameConverter seems to work only with images of BufferedImage.TYPE_3BYTE_BGR(5) type. I've written some code that helps to check it out. I used square image with 4 quarters (rgb colors and last one left transparent). I tried to convert different types of this BufferedImage to Frame and than back. Resulting image (together with initial which is first) I draw on final image side by side:

import org.bytedeco.javacv.FrameConverter;
import org.bytedeco.javacv.Java2DFrameConverter;
import static org.bytedeco.javacpp.avutil.*;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.*;
import java.io.*;

    public static void main(){
        int types = 7;
        BufferedImage image = new BufferedImage(100,100,6);
        Graphics g = image.getGraphics();
        g.setColor(new Color(255, 0, 0, 255));
        g.fillRect(0, 0, 50, 50);

        g.setColor(new Color(0, 255, 0, 255));
        g.fillRect(50, 0, 50, 50);

        g.setColor(new Color(0, 0, 255, 255));
        g.fillRect(0, 50, 50, 50);

        BufferedImage result = new BufferedImage(types*100,100, 6);
        Graphics resultingGraphics = result.createGraphics();
        resultingGraphics.drawImage(image, 0, 0, 100, 100, null);

        for (int type=1; type<types; type++){
            BufferedImage typed = convertToBufferedImageOfType(image, type);

            Java2DFrameConverter converter = new Java2DFrameConverter();
            Frame frame1 = converter.getFrame(typed);

            Java2DFrameConverter newConverter = new Java2DFrameConverter();
            BufferedImage convertedBack = newConverter.getBufferedImage(frame1);

            resultingGraphics.drawImage(convertedBack, type*100,0, 100, 100, null);
        }

        try {
            ImageIO.write(result, "png", new File("resulting image"));
        } catch (Exception e){}
    }

    public static BufferedImage convertToBufferedImageOfType(BufferedImage sourceImage, int targetType) {
        BufferedImage image = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), targetType);
        image.getGraphics().drawImage(sourceImage, 0, 0, null);

        return image;
    }

Here is the result: resulting_image You can see that output is not correct for most of the types. For 1st and 4th types we don't get anything. It might seem that type TYPE_4BYTE_ABGR(6) works fine, but it is not, you can see that by trying to use this type in FFmpegFrameRecorder. For example blue image (-1,-1,0,0) turns into yellow in video. It is so because AV_PIX_FMT_RGBA pixel format is used I think. For type TYPE_3BYTE_BGR(5) we use AV_PIX_FMT_BGR24 pixel format, so channels go to the proper places.

Contributor guide