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

如何在JavaSE中将字节数组转换为图像,java,image,graphics,Java,Image,Graphics,在JavaSE中,将原始字节数组转换为图像的正确方法是什么。 数组由字节组成,其中每三个字节代表一个像素,每个字节代表相应的RGB组件 有人能推荐一个代码示例吗 谢谢, Mike假设您知道图像的高度和宽度 BufferedImage img=new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); for(int r=0; r<height; r++) for(int c=0; c<width; c++) { in

在JavaSE中,将原始字节数组转换为图像的正确方法是什么。 数组由字节组成,其中每三个字节代表一个像素,每个字节代表相应的RGB组件

有人能推荐一个代码示例吗

谢谢,
Mike

假设您知道图像的高度和宽度

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);
}
BufferedImage img=新的BufferedImage(宽度、高度、BufferedImage.TYPE\u INT\u RGB);

对于(int r=0;r有一个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);
BufferedImage img=新的BufferedImage(宽度、高度、BufferedImage.TYPE\u INT\u RGB);
int[]原始=新int[data.length*4/3];
对于(int i=0;i((data[3*i+0]&0xFF)您可以使用Raster类来完成。它更好,因为它不需要迭代和复制字节数组

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

folkyatina的方法在RGB值按B、G、R顺序排列时有效,但如果它们按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);

假设原始数据是1d数组,如:

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();

因此,遍历数组是我在这里的最佳选择?感觉一定有某种方法可以接受数组作为参数,并一次性填充/重新创建图像。可能与光栅类有关?据我所知,这与光栅不太熟悉。如果这遵循标准图像格式,您可以使用ImageIO类,但这是我知识的极限。你也可以这样做:
intrgb=((int)colors[以]这种方式你可以解决符号/无符号问题:frameImg.setRGB(x,y,((data[i0]&0xFF)|((data[i0+1]&0xFF)尽管被接受,但这个答案似乎并不正确。如果
colors
是一个rgb数组(其中R,G,&B是单个字节),索引的增量不应该超过每个循环1吗?最终我没有找到比这更好的:for(int y=0;y字节数组的维数是多少?是一维数组、二维数组还是三维数组?谢谢你的发布。它真的很方便!