0

The user can browse to an image file. I want to persist the selected file to a db (derby db), in BLOB Column. to do that, I need to convert Image object to an array of bytes (byte[]), and to retreive it I need to: byte[] -> Image.

So I search and found this: from this question

pure java fx solution trace ( == you will have to fill in missing points :)

Image i = logo.getImage();
PixelReader pr = i.getPixelReader();
PixelFormat f = pr.getPixelFormat();

WriteablePixelFromat wf = f.getIntArgbInstance(); //???

int[] buffer = new int[size as desumed from the format f, should be  i.width*i.height*4];

pr.getPixels(int 0, int 0, int i.width, i.height, wf, buffer, 0, 0);

I implemented in this way:

private ImageByteInfo imageToByteArray(Image i){
        PixelReader pr = i.getPixelReader();
        WritablePixelFormat<ByteBuffer> wf = PixelFormat.getByteBgraInstance();

        byte[] buffer = new byte[(int) (i.getWidth() * i.getHeight() *4)];

        pr.getPixels(0, 0, (int) i.getWidth(), (int) i.getHeight(), wf, buffer, 0, 0);

        return new ImageByteInfo(buffer, (int) i.getWidth(), (int) i.getHeight()) ;
    }

Except that when I investigate the buffer array. I found that only the first 4096 entry are valid (have number), ALL THE REST of the array is 0 0 0 0 0 0.

So how Can I fix this?? Thanks.

And this the method that retreive The image from The unfixed array. is this is correct or not?

private Image byteArrayToImage(ImageByteInfo imageArray){

        WritablePixelFormat<ByteBuffer> wf = PixelFormat.getByteBgraInstance();

        WritableImage writableimage = new WritableImage(imageArray.getWidth(), imageArray.getHeight());

        PixelWriter pixelWriter = writableimage.getPixelWriter();

        pixelWriter.setPixels(0, 0, imageArray.getWidth(), imageArray.getHeight(), wf, imageArray.getByteImage(), 0, 0);

        return writableimage;
    }

Note: Not interested in File System Storage, and it need to be pure JavaFX (no Swing or AWT)

Community
  • 1
  • 1
usertest
  • 2,140
  • 4
  • 32
  • 51
  • I'm not sure why you feel the need to avoid ImageIO, but by doing so, you are storing uncompressed bytes. Is that really what you want? Images can take up quite a lot of space. – VGR May 03 '16 at 17:56
  • 2
    @VGR well I want The application that I'm writting to be 100% JavaFX, no AWT, no Swing, even if it's just a utility line of code (like in this case). And for image compression. I don't need that for now. maybe I will add that in a future version. – usertest May 04 '16 at 13:37

1 Answers1

2

In

pr.getPixels(0, 0, (int) i.getWidth(), (int) i.getHeight(), wf, buffer, 0, 0);

the last argument (the scanlineStride) is the offset into the array when you progress from one row to the next row in the image. Since you set it at zero, you are not incrementing the array index and effectively only writing one "row" of the array.

Since this format uses 4 bytes per pixel, you need a scanline stride of 4*imageArray.getWidth():

pr.getPixels(0, 0, (int) i.getWidth(), (int) i.getHeight(), wf, buffer, 0, 4*imageArray.getWidth());

Similarly,

pixelWriter.setPixels(0, 0, imageArray.getWidth(), imageArray.getHeight(), wf, imageArray.getByteImage(), 0, 4*imageArray.getWidth());
James_D
  • 201,275
  • 16
  • 291
  • 322
  • hh funny, I already tried that. but I forgot to apply the change in the opposite direction. Thanks a lot Man for adding that edit, without it this would not work. you're a smart man. – usertest May 03 '16 at 16:05