在 JPG 图像中隐藏消息
Posted
技术标签:
【中文标题】在 JPG 图像中隐藏消息【英文标题】:Hiding message in JPG image 【发布时间】:2013-05-14 15:43:52 【问题描述】:我正在尝试将 a 隐藏在图像中,它可以与 .bmp 和 .png 一起正常工作,但是当我将图像写为 JPG 并尝试检索隐藏的消息时,它不起作用。
我的程序,首先读取格式的图像(bmp
,gif
,jpg
,png
)写入消息以隐藏并保存,以便我们再次读取并提取消息。
当我用bmp
或png
保存它时,它工作正常,但用jpg
保存并尝试提取消息时它不起作用。
ImageIO.write(bimg, "png", outputfile);//working
ImageIO.write(bimg, "png", outputfile);//not working
我应该怎么做才能使它适用于 JPEG?
注意:我将每个像素读取为具有 ARGB 值的 4 位整数,并更改 R、G、B 的 LSB 以隐藏消息。
public void stegnography(BufferedImage bimg,String msg,String filename)
int w=bimg.getWidth();
int h=bimg.getHeight();
//***************************************
// String msg="Hide this message:)";
System.out.println("message="+msg+" length="+msg.length());
//***************************************
if(msg.length()>255 )
jLabel3.setText("MESSAGE IS LARGE THAN 255 CHARACTERS");
else if( msg.length()*11 >w*h)
jLabel3.setText("Image is too small");
else
//-------------------------------------------
byte[] msgbytes= msg.getBytes();
int msglendecode= (bimg.getRGB(0,0)>>8)<<8;
msglendecode |= msg.length();
bimg.setRGB(0, 0,msglendecode );//hidig msg length at first position
//System.out.println("\npixel at position (0,0) ");
// bitpattern(bimg.getRGB(0,0) );
for(int i=1,msgpos=0,row=0,j=0; row<h ;row++ )
for(int col=0;col<w && j<msgbytes.length ;col++,i++ )
if (i%11==0)
int rgb = bimg.getRGB(col,row);
int a=((rgb >> 24) & 0xff);
int r = (((rgb >> 16) & 0xff)>>3)<<3;
r=r|(msgbytes[msgpos]>>5);
int g = (((rgb >> 8) & 0xff)>>3)<<3;
g=g|((msgbytes[msgpos]>>2)& 7);
int b = ((rgb & 0xff)>>2)<<2;
b=b|(msgbytes[msgpos]&0x3);
rgb=0;
rgb=(rgb|(a<<24));
rgb=(rgb|(r<<16));
rgb=(rgb|(g<<8));
rgb=(rgb|b);
bimg.setRGB(col,row,rgb);
msgpos++;
j++;
//bitpattern(bimg.getRGB(col,row));
//for 2
//for 1
ImageIcon image = new ImageIcon(bimg);
jLabel3.setIcon(image);
try
// File outputfile = new File("c:/Users/yathestha/Documents/"+filename);
File outputfile = new File("c:/Users/yathestha/Documents/outpng.png");
ImageIO.write(bimg, "png", outputfile);
catch (IOException e)
System.out.println("error in saving image ");
//-------------------------------------------------
//else
// decoding part----------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////
private void decodestegnography(BufferedImage bimg)
System.out.println("in decode");
int w=bimg.getWidth(),h=bimg.getHeight();
bitpattern(bimg.getRGB(0, 0));
int msglength=(bimg.getRGB(0, 0)&0xff);
bitpattern(msglength);
System.out.println("Message Length="+msglength);
jTextField1.setText("");
for(int row=0,j=0,i=1; row<h ;row++ )
for(int col=0;col<w && j<msglength ;col++ ,i++)
if (i%11==0)
int result=bimg.getRGB(col,row);
int charatpos = (((result >> 16) & 0x7) << 5);
charatpos |= (((result >> 8) & 0x7) << 2);
charatpos |= ((result & 0x3));
jTextField1.setText(jTextField1.getText()+ (char)charatpos);
j++;
System.out.println("decoding done");
//function
【问题讨论】:
可能同样的问题***.com/questions/16130177/… 如需尽快获得更好的帮助,请发帖SSCCE。 JPG 有损。这意味着它会丢弃一些数据。是什么让您认为您的消息应该能够经受住有损压缩? 我读过这篇文章,但应该有办法实现这一点,因为我想在 facebook 图片封面上应用它 嘿,你能解释一下你的代码吗? 【参考方案1】:对于 jpeg 隐写术,要么将结果保存为无损 jpeg,要么简单地使用不同的隐写方法。我唯一知道的是摆弄离散余弦变换系数(DCT)。但是,您需要注意舍入错误,因此检索您的秘密将是有损的。
我不喜欢 DCT,也没有深入研究,但 here 是 2007 年的一篇论文,声称 jpeg 无损隐写术。请注意,该算法比空间域中的随意 LSB 替换要复杂得多。在频域隐藏数据也意味着更低的隐藏能力,我不知道这是否对你有用。如果您有兴趣但无法访问该论文,我们可以私下整理。
【讨论】:
“无法访问论文,我们可以私下解决。” 这个答案很好,直到那时。链接的论文是 我只是想把这个应用到Facebook的封面图片上,现在似乎有点困难 是的,我在学术界,可以免费获取论文。我不打算分享我的帐户,但我想作为一个难得的帮助,我可以发送 pdf。这完全是我的想法。 :)【参考方案2】:您可能必须更改 JPEG 以获得 100% 的编码质量 - 这会显着增加字节大小(很多)。
请参阅this thread,了解如何以可控的压缩/质量编码为 JPG。左边的滑块是用来控制关卡的。
【讨论】:
以上是关于在 JPG 图像中隐藏消息的主要内容,如果未能解决你的问题,请参考以下文章