How to convert array of bytes into Image in Java SE

后端 未结 5 1336
悲&欢浪女
悲&欢浪女 2020-12-09 23:07

What is the right way to convert raw array of bytes into Image in Java SE. array consist of bytes, where each three bytes represent one pixel, with each byte for correspondi

相关标签:
5条回答
  • 2020-12-09 23:12

    You can do it using Raster class. 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);
    
    0 讨论(0)
  • 2020-12-09 23:24

    There is a setRGB variant which accepts an int array of RGBA values:

    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.

    0 讨论(0)
  • 2020-12-09 23:26

    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).

    0 讨论(0)
  • 2020-12-09 23:26

    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:

        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);
    
    0 讨论(0)
  • 2020-12-09 23:37

    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();
    
    0 讨论(0)
提交回复
热议问题