Convert byte array of data type TYPE_4BYTE_ABGR to BufferedImage

狂风中的少年 提交于 2019-12-13 01:48:14

问题


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?


回答1:


Might not be very efficient, but a BufferedImage can be converted to another type this way:

public static BufferedImage convertToType(BufferedImage image, int type) {
    BufferedImage newImage = new BufferedImage(image.getWidth(), image.getHeight(), type);
    Graphics2D graphics = newImage.createGraphics();
    graphics.drawImage(image, 0, 0, null);
    graphics.dispose();
    return newImage;
}

About the method you want to be implemented, you would have to know the width or height of the image to convert a byte[] to a BufferedImage.

Edit:
One way is converting the byte[] to int[] (data type TYPE_INT_ARGB) and using setRGB:

int[] dst = new int[width * height];
for (int i = 0, j = 0; i < dst.length; i++) {
    int a = src[j++] & 0xff;
    int b = src[j++] & 0xff;
    int g = src[j++] & 0xff;
    int r = src[j++] & 0xff;
    dst[i] = (a << 24) | (r << 16) | (g << 8) | b;
}
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
image.setRGB(0, 0, width, height, dst, 0, width);



回答2:


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@<hash>: 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);


来源:https://stackoverflow.com/questions/30237994/convert-byte-array-of-data-type-type-4byte-abgr-to-bufferedimage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!