Bouowmx
Bouowmx

Reputation: 23

JavaFX reading raw RGB image

I have trouble reading a raw RGB image in JavaFX.

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelFormat;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class JavaFXRgb extends Application {
    @Override public void start(Stage stage) {
        FileInputStream fileInputStream = null;
        try {fileInputStream = new FileInputStream("0.rgb");}
        catch (FileNotFoundException exception) {exception.printStackTrace();}
        byte[] imageBytes = new byte[2_764_800]; //1280x720
        try {for (int bytesRead = 0; bytesRead < imageBytes.length; ) {bytesRead += fileInputStream.read(imageBytes, bytesRead, imageBytes.length - bytesRead);}}
        catch (IOException exception) {exception.printStackTrace();}
        WritableImage writableImage = new WritableImage(1280, 720);
        PixelWriter pixelWriter = writableImage.getPixelWriter();
        pixelWriter.setPixels(0, 0, 1280, 720, PixelFormat.getByteRgbInstance(), imageBytes, 0, 0);
        Group group = new Group(new ImageView(writableImage));
        Scene scene = new Scene(group);
        stage.setScene(scene);
        stage.sizeToScene();
        stage.show();
    }
}

The original image compressed to PNG (Fair use: minimal usage: one image from set): Original image

Use ImageMagick convert "0.png" "0.rgb" to obtain the file I used.

Image in JavaFX: Image in JavaFX

The loaded JavaFX image appears to repeat the top row.

I tried fiddling with the PixelFormat in the line:

pixelWriter.setPixels(0, 0, 1280, 720, PixelFormat.getByteRgbInstance(), imageBytes, 0, 0);

but no successful results. I am able to load the image in GIMP though.

Upvotes: 2

Views: 1252

Answers (1)

James_D
James_D

Reputation: 209438

getByteRgbInstance() returns a pixel format in which there are three bytes per pixel: one each for red, green, blue, in order. The last argument to the setPixels method is the difference in offset in the array from the beginning of one row to the beginning of the next row. If you provide zero for this, it's just going to repeatedly read the same data for each row.

If you are using this format with an image width of 1280, the scanlineStride should be 1280*3 = 3840. So try:

pixelWriter.setPixels(0, 0, 1280, 720, 
    PixelFormat.getByteRgbInstance(), 
    imageBytes, 0, 1280*3);

If that fails, you probably need to check the documentation for ImageMagick to see the actual format that your data is being stored in.

Upvotes: 2

Related Questions