隐藏JPG图像中的消息 [英] Hiding message in JPG image

查看:158
本文介绍了隐藏JPG图像中的消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图隐藏一个图像,它可以正常工作.bmp& .png但是当我将图像写为JPG并尝试检索隐藏的消息时它无法正常工作。
我的程序,首先读取格式的图像( bmp gif jpg png )写消息以隐藏并保存它,以便我们可以再次读取它并提取消息。
当我用 bmp png 保存时,它可以正常工作但是用 jpg 并尝试提取它不起作用的消息。

I am trying to hide a in an image it's working fine with .bmp & .png but when I write image as JPG and try to retrieve the hidden message it is not working. My procedure, first read an image in format (bmp, gif, jpg,png) write message to hide and save it so that we can again read it and extract the message. When i save it with bmp or png it works fine but when saving with jpg and try to extract the message it doesn't work.

 ImageIO.write(bimg, "png", outputfile);//working
 ImageIO.write(bimg, "png", outputfile);//not working 

我该怎么做才能让它适用于JPEG?

What should I do to make it work for JPEG?

注意:我正在阅读每一个像素为4位整数,具有ARGB值并更改R,G,B的LSB以隐藏消息。

note: I am reading every pixel as 4 bit integer with ARGB value and changing LSB of R,G,B to hide message.

    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


推荐答案

对于jpeg隐写术要么将结果保存为无损jpeg,要么只使用不同的stegographic方法。我所知道的唯一一个是摆弄离散余弦变换系数(DCT)。但是,您需要注意舍入错误,因此检索您的秘密将是有损的。

For jpeg steganography either save your result as a lossless jpeg, or simply use a different stegographic method. The only one I know is fiddling with the Discrete Cosine Transform coefficients (DCT). However, you need to be aware of rounding errors and as such the retrieval of your secret will be lossy.

我不喜欢DCT而我没有考虑过它很多,但这里是2007年的一篇论文,声称jpeg无损隐写术。请注意,该算法比空间域中的偶然LSB替换要复杂得多。隐藏频域中的数据也意味着更低的隐藏容量,我不知道这是否会为您服务。如果您有兴趣并且无法访问该论文,我们可以私下对其进行排序。

I don't favour DCT and I haven't looked into it a lot, but here is a paper from 2007 which claims jpeg lossless steganography. Be warned that the algorithm is much more complex than your casual LSB substitution in the spatial domain. Hiding data in the frequency domain also means lower hiding capacity and I don't know whether this will serve you. If you are interested and can't access the paper, we can sort this out privately.

这篇关于隐藏JPG图像中的消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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