简体   繁体   English

如何在 Java SE 中将字节数组转换为图像

[英]How to convert array of bytes into Image in Java SE

What is the right way to convert raw array of bytes into Image in Java SE.在 Java SE 中将原始字节数组转换为 Image 的正确方法是什么。 array consist of bytes, where each three bytes represent one pixel, with each byte for corresponding RGB component.数组由字节组成,其中每三个字节代表一个像素,每个字节代表相应的 RGB 分量。

Can anybody suggest a code sample?有人可以建议代码示例吗?

Thanks, Mike谢谢,迈克

You can do it using Raster class.您可以使用 Raster 类来完成。 It's better because it does not require iterating and copying of byte arrays.它更好,因为它不需要迭代和复制字节数组。

 byte[] raw = new byte[width*height*3]; // raw bytes of our image
 DataBuffer buffer = new DataBufferByte(raw, raw.length);

 //The most difficult part of awt api for me to learn
 SampleModel sampleModel = new ComponentSampleModel(DataBuffer.TYPE_BYTE, width, height, 3, width*3, new int[]{2,1,0});

 Raster raster = Raster.createRaster(sampleModel, buffer, null);

 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
 image.setData(raster);

Assuming you know the height and width of the image.假设您知道图像的高度和宽度。

BufferedImage img=new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for(int r=0; r<height; r++)
for(int c=0; c<width; c++)
{
  int index=r*width+c;
  int red=colors[index] & 0xFF;
  int green=colors[index+1] & 0xFF;
  int blue=colors[index+2] & 0xFF;
  int rgb = (red << 16) | (green << 8) | blue;
  img.setRGB(c, r, rgb);
}

Roughly.大致。 This assumes the pixel data is encoded as a set of rows;这假设像素数据被编码为一组行; and that the length of colors is 3 * width * height (which should be valid).并且颜色的长度是 3 * 宽 * 高(应该是有效的)。

folkyatina's approach works if your RGB values are in B,G,R order, but if they are in R,G,B order I have found the following code to work:如果您的 RGB 值按 B、G、R 顺序排列,folkyatina 的方法有效,但如果它们按 R、G、B 顺序排列,我发现以下代码可以工作:

    DataBuffer rgbData = new DataBufferByte(rgbs, rgbs.length);

    WritableRaster raster = Raster.createInterleavedRaster(
        rgbData, width, height,
        width * 3, // scanlineStride
        3, // pixelStride
        new int[]{0, 1, 2}, // bandOffsets
        null);

    ColorModel colorModel = new ComponentColorModel(
        ColorSpace.getInstance(ColorSpace.CS_sRGB),
        new int[]{8, 8, 8}, // bits
        false, // hasAlpha
        false, // isPreMultiplied
        ComponentColorModel.OPAQUE,
        DataBuffer.TYPE_BYTE);

    return new BufferedImage(colorModel, raster, false, null);

There is a setRGB variant which accepts an int array of RGBA values:有一个 setRGB 变体,它接受 RGBA 值的 int 数组:

BufferedImage img=new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] raw = new int[data.length * 4 / 3];
for (int i = 0; i < data.length / 3; i++) {
    raw[i] = 0xFF000000 | 
        ((data[3 * i + 0] & 0xFF) << 16) |
        ((data[3 * i + 1] & 0xFF) << 8) |
        ((data[3 * i + 2] & 0xFF));
}
img.setRGB(0, 0, width, height, raw, 0, width);

The performance characteristics is similar to CoderTao 's solution.性能特点类似于CoderTao的解决方案。

Assuming that your raw data is a 1d array like:假设您的原始数据是一维数组,如:

byte[] imageBytes = new byte[1024];
// transform to bufferImage
BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(imageBytes));
// if you want to do some operations to the image, like resize, 
// use the lib (net.coobird.thumbnailator)
BufferedImage image = Thumbnails.of(bufferedImage).forceSize(WIDTH, HEIGHT)
                                .outputFormat("bmp").asBufferedImage();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM