Pure JavaFX: convert Image to bytes Array (+ oppos

2019-08-30 07:35发布

问题:

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)

回答1:

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());