将字节数组转换为png

时间:2016-04-04 16:19:01

标签: java image png byte bufferedimage

我使用以下代码从图像中获取了一个字节数组。

for(String name : family) {
     // do stuff with name
}

然后我使用以下代码将这些字节转换回png图像。

String path = "/home/mypc/Desktop/Steganography/image.png";
File file = new File(path);
BufferedImage bfimage = ImageIO.read(file);

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bfimage, "png", baos);
baos.flush();
byte[] img_in_bytes = baos.toByteArray();
baos.close();

如果我只执行这段代码就完全没问题。但是,如果我尝试修改其间的一些字节,请这样说:

BufferedImage final_img = ImageIO.read(new ByteArrayInputStream(img_in_bytes));
File output_file = new File("Stegano2.png");
ImageIO.write(final_img, "png", output_file);

和我的方法" Inset_number_to_image"是这样的:

    Insert_number_to_image(image_in_bytes,  10);

然后,当我使用上面提到的相同代码将修改后的字节数组保存为png图像时,我收到此错误:

static void Insert_number_to_image(byte[] image, int size){     
    byte[] size_in_byte = new byte[4];
    size_in_byte[0] = (byte)(size >>> 0);
    size_in_byte[1] = (byte)(size >>> 8);
    size_in_byte[2] = (byte)(size >>> 16);
    size_in_byte[3] = (byte)(size >>> 24);

    byte temp;
    int count = 0;

    for(int i=0; i<4; i++)
    {
        for(int j=0; j<8; j++)
        {
            temp = size_in_byte[i];
            temp = (byte)(temp >>> j);
            temp = (byte)(temp & 1);
            if(temp == 1)
            {
                image[count] = (byte)(image[count] | 1);
            }
            else if(temp == 0)
            {
                image[count] = (byte)(image[count] & (byte)(~(1)));
            }
            count++;
        }
    }
}

1 个答案:

答案 0 :(得分:4)

What you're using is the raw bytestream of a PNG image. PNG is a compressed format, where the bytestream doesn't reflect any of the pixel values directly and even changing one byte might irreversibly corrupt the file.

What you want instead is to extract the pixel data to a byte array with

byte[] pixels = ((DataBufferByte) img.getRaster().getDataBuffer()).getData();

Now you can modify the pixel values however you want. When you are ready to save that back to a file, convert the pixel byte array to a BufferedImage by putting your pixel array in a DataBufferByte object and passing that to a WriteableRaster, which you then use to create a BufferedImage.

Your method would work for formats where the raw bytestream does directly represent the pixels, such as in BMP. However, even then you'd have to skip the first few bytes to avoid corrupting the header.

相关问题