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?
-
Is your byte array an image file, or is it just pixel data? Also see http://stackoverflow.com/questions/12705385/how-to-convert-a-byte-to-a-bufferedimage-in-java (possible duplicate) – Radiodef May 14 '15 at 13:12
-
It's just pixed data. will make it clear – July May 14 '15 at 13:51
2 Answers
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);

- 26,314
- 7
- 65
- 111
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);

- 3,833
- 6
- 25
- 33
-
Thanks for the response, however what I want is creating a BufferedImage from byte array with type XXX, not from existing image, I update my question to make it clear, could you please help? – July May 14 '15 at 14:07
-
@July I answered that too, it's impossible unless you know the width or height. Why the downvote? Edit: I see you changed the question. – Bubletan May 14 '15 at 14:16
-
I didn't downvote, maybe another guy did that? I edit the question to make it clear, sorry for the misleading before if it did. – July May 14 '15 at 14:24
-