我读的图像,并改变它。但更改不会被保存 [英] I am reading an image and changing it. But the changes are not being saved

查看:108
本文介绍了我读的图像,并改变它。但更改不会被保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现隐身。
我阅读一个图象a.jpeg,并通过在偏离50开始至少显著位改变其连续7个字节在它插入一个字节。
这是因为当我打印的最后位相应地变化字节成功完成。
然后我保存为ao.jpeg。但是,当我从50读取的字节值,他们不是因为一旦我保存的相同。
这里是我的code

I am trying to implement a steganography. I am reading an image "a.jpeg" and inserting a byte in it by changing its consecutive 7 bytes at the least significant bit starting from offset 50. This is done successfully as when I print the bytes the last bits are changed accordingly. Then I saved it as "ao.jpeg". But when I am reading the byte values from 50, they are not the same as the once i saved. here's my code

public static void main(String[] args) throws IOException {
        BufferedImage inputImage = ImageIO.read(new File("a.jpeg"));
        int offset=50;
        byte data = 7;
        byte[] image = get_byte_data(inputImage);//function converts bufferedimage to byte array
        //add data at end of each byte starting from offset
        System.out.println("bytes altered are :");
        for(int bit=7; bit>=0; --bit, ++offset)//for each bit of data
            {
            int b = (data >>> bit) & 1;
            image[offset] = (byte)((image[offset] & 0xFE) | b );
            String s1 = String.format("%8s", Integer.toBinaryString(image[offset] & 0xFF)).replace(' ', '0');
            System.out.println(s1);
            }
        //write changed image to ao.jpeg
        BufferedImage outputImage = ImageIO.read(new ByteArrayInputStream(image)); 
        File outputfile = new File("ao.jpeg");
        ImageIO.write(outputImage,"jpeg",outputfile);
        //read data from ao.jpeg
        System.out.println("bytes from encoded image are :");
        byte result=0;
        offset=50;
        BufferedImage oImage = ImageIO.read(new File("aoc.jpeg"));
        byte[] image1 = get_byte_data(oImage);//function converts bufferedimage to byte array
            for(int i=0; i<8; i++, ++offset)
             {
             result = (byte)((result << 1) | (image1[offset] & 1));
             String s1 = String.format("%8s", Integer.toBinaryString(image1[offset] & 0xFF)).replace(' ', '0');
             System.out.println(s1);
             }
            System.out.println("recovered data is :");
            System.out.print(result);
        }

输出样本:
插入的数据是7。如果发现它是在形成7各自字节的最低显著位。
但是,当我看了一遍它是随机字节。

output sample : data inserted is 7. If you notice the least significant bit of each byte it is forming 7. But when i read it again it is random bytes.

bytes altered are :
00010100
00011100
00011010
00011110
00011110
00011101
00011011
00011101
bytes from encoded image are :
00011110
00011101
00011010
00011100
00011100
00100000
00100100
00101110
recovered data is :
64

正如康斯坦丁V. Salikhov建议我尝试了不同的文件格式(GIF)和它的工作。
但有什么办法,我可以使用JPEG?

As suggested by Konstantin V. Salikhov I tried different file format (gif) and it worked. But is there any way i can use "jpeg"?

推荐答案

由于Salinkov建议,JPEG格式导致数据COM pression。总之你做了什么:

Why your approach fails

As Salinkov suggested, the jpeg format causes data compression. To summarise what you did:


  • 您字节数组加载的图像数据。

  • 您修改了一些字节。

  • 您加载的字节数组作为图像。

  • 您以JPEG格式保存这张图片,这将导致RECOM pression。

这就是你的方法分崩离析。无损格式不会产生这些问题,这就是为什么的gif工作。或PNG,BMP,等...

That's where your method falls apart. A lossless format will not produce these problems, which is why gif works. Or png, bmp, etc...

Weeeeell,没有,真的没有。首先,我们需要了解JPEG图像持有什么样的数据。

Weeeeell, no, not really. First, we need to understand what kind of data a jpeg image holds.

简短的回答是,个别字节不符合实际像素的图像中。

The short answer is that individual bytes don't correspond to actual pixels in the image.

长故事是,拆分采用8x8阵列图像,并采取DCT获得的频率系数。一个量化步骤之后,很多人会变成0,特别是频率较高的系数(对DCT阵列右下角 - <一个href=\"http://semitau-kecamatan.kpt.co.id/_buku_manual/_baca_blob.php?book=lain&kodegb=f26447bde52f84f3fea4eadfe2268e56.png\"相对=nofollow>在这里看到)。这是JPEG的有损一步。你对一些可容忍的图像失真(信息丢失)牺牲更高频率的系数。现在,在保存是非零系数的基础上,其在矩阵中的位置,即(0,0,-26),(0,1,-3),等,这可以进一步玉米pressed与霍夫曼编码。顺便说一下,变化的任何一个频率分量影响所有64个象素。

The long story is that you split the image in 8x8 arrays and take the DCT to obtain the frequency coefficients. After a quantisation step, many of them will become 0, especially the higher frequency coefficients (bottom right of the DCT array - see here). This is the lossy step of jpeg. You sacrifice higher frequency coefficients for some tolerable image distortion (loss of information). Now, what you save is the non-zero coefficients, based on their location in the matrix, i.e. (0, 0, -26), (0, 1, -3), etc. This can be further compressed with Huffman coding. By the way, changing any one frequency component affects all 64 pixels.

因此​​,如何为JPEG隐写术通常做什么?它主要利用了JPEG编码过程:

So how is jpeg steganography normally done? It mostly follows the jpeg encoding process:


  • 在8x8的阵列分割图像。

  • DCT每个8x8阵列和quantise的系数。

现在我们所获得的量化DCT系数,我们采取从JPEG编码过程中断。

Now we have obtained the quantised DCT coefficients and we take a break from the jpeg encoding process.


  • 通过改变量化系数的值取一些隐写算法。

  • Apply some steganographic algorithm by changing the value of the quantised coefficients.

霍夫曼COM preSS的系数,并继续用这些修改的DCT系数的JPEG编码过程的其余部分。

Huffman compress the coefficients and continue with the rest of the jpeg encoding process with these modified DCT coefficients.

这篇关于我读的图像,并改变它。但更改不会被保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆