2

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.

Bouowmx
  • 23
  • 5

1 Answers1

2

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.

James_D
  • 201,275
  • 16
  • 291
  • 322
  • Thanks for clarifying scanlineStride. I skimmed it and I thought it had something to do with BMP row padding. – Bouowmx Feb 10 '16 at 23:02