Convert byte array of data type TYPE_4BYTE_ABGR to BufferedImage

前端 未结 2 1369
说谎
说谎 2021-01-25 10:38

I have a byte array with type TYPE_4BYTE_ABGR, and I know its width and height, I want to change it to BufferedImage, any ideas?

2条回答
  •  再見小時候
    2021-01-25 11:28

    The fastest way to create a BufferedImage from a byte array in TYPE_4BYTE_ABGR form, is to wrap the array in a DataBufferByte and create an interleaved WritableRaster from that. This will make sure there are no additional byte array allocations. Then create the BufferedImage from the raster, and a matching color model:

    public static void main(String[] args) {
        int width = 300;
        int height = 200;
    
        int samplesPerPixel = 4; // This is the *4BYTE* in TYPE_4BYTE_ABGR
        int[] bandOffsets = {3, 2, 1, 0}; // This is the order (ABGR) part in TYPE_4BYTE_ABGR
    
        byte[] abgrPixelData = new byte[width * height * samplesPerPixel];
    
        DataBuffer buffer = new DataBufferByte(abgrPixelData, abgrPixelData.length);
        WritableRaster raster = Raster.createInterleavedRaster(buffer, width, height, samplesPerPixel * width, samplesPerPixel, bandOffsets, null);
    
        ColorModel colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
    
        BufferedImage image = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null);
        System.out.println("image: " + image); // Should print: image: BufferedImage@: type = 6 ...
    }
    

    Note however, that this image will be "unmanaged" (some HW accelerations will be disabled), because you have direct access to the pixel array.

    To avoid this, create the WritableRaster without the pixels, and copy the pixels into it. This will use twice as much memory, but will keep the image "managed" and thus possible better display performance:

    // Skip creating the data buffer
    WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height, samplesPerPixel * width, samplesPerPixel, bandOffsets, null);
    raster.setDataElements(0, 0, width, height, abgrPixelData);
    // ...rest of code as above.
    

    You could even do this (which might be more familiar):

    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
    WritableRaster raster = image.getRaster();
    raster.setDataElements(0, 0, width, height, abgrPixelData);
    

提交回复
热议问题