5 Replies Latest reply on Feb 24, 2010 4:15 PM by 843802

    Pixel Values are Chaning After IOImage.write operation

    843802
      I have read a GrayScale image using BufferedImage by read operation and then i saved all my pixel values to a byte array by using
      byte data[];
      DataBufferByte buffer = (DataBufferByte) image.getRaster().getDataBuffer();
      data = buffer.getData();
      now i changed all the LSBs of byte array ie., from 0 to 1 or from 1 to 0 by using
      if(image.data%2==0) image.data[i] = (byte)(image.data[i] | 0x01);
      else if(image.data[i]==0) image.data[i] = (byte)1;
      else image.data[i] = (byte)(image.data[i] & 0xFE);
      now i saved the image by using IOImage.write operation with the same BufferedImage object.. next time when I print the pixel values, they are not the same as I have changed them.. I mean they are showing different values instead of showing the same values with opposite LSB.. I dont know why that is happening..
      
      Somebody please help                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
        • 1. Re: Pixel Values are Chaning After IOImage.write operation
          843802
          You're probably saving the image in some lossy compression format like jpeg. By definition, you loose information with a lossy compression. For steganography, you'll want to use a lossless format like png.
          • 2. Re: Pixel Values are Chaning After IOImage.write operation
            843802
            Hmm.. I dont think so.. Because as soon as I saw your post I tried the same pixel morphing technique for a png file instead of a jpg file.. and I got the same results..

            I dont know how far this can help us, but I observed some pattern with the distortion in pixel values from what I have explicitly mentioned..

            Here are some sample values:
            Value_I_Have_Given_For_Pixel                     Value_I_Am_Obtaining_While_Reading
            
                     1                                     -                          1
                     2                                     -                          1
                     3                                     -                          2
                     4                                     -                          2
                     5                                     -                          3
                     6                                     -                          3
                     7                                     -                          4
                     8                                     -                          5
                     9                                     -                          6
                     10                                    -                          7
                     20                                    -                          20
            • 3. Re: Pixel Values are Chaning After IOImage.write operation
              843802
              here are 100 samples
              0 --> 0 --> 0
              1 --> 1 --> 1
              2 --> 1 --> 1
              3 --> 2 --> 10
              4 --> 2 --> 10
              5 --> 3 --> 11
              6 --> 3 --> 11
              7 --> 4 --> 100
              8 --> 5 --> 101
              9 --> 6 --> 110
              10 --> 7 --> 111
              11 --> 8 --> 1000
              12 --> 9 --> 1001
              13 --> 10 --> 1010
              14 --> 12 --> 1100
              15 --> 13 --> 1101
              16 --> 15 --> 1111
              17 --> 17 --> 10001
              18 --> 18 --> 10010
              19 --> 19 --> 10011
              20 --> 20 --> 10100
              21 --> 20 --> 10100
              22 --> 21 --> 10101
              23 --> 22 --> 10110
              24 --> 23 --> 10111
              25 --> 24 --> 11000
              26 --> 25 --> 11001
              27 --> 26 --> 11010
              28 --> 27 --> 11011
              29 --> 28 --> 11100
              30 --> 30 --> 11110
              31 --> 31 --> 11111
              32 --> 32 --> 100000
              33 --> 33 --> 100001
              34 --> 34 --> 100010
              35 --> 35 --> 100011
              36 --> 36 --> 100100
              37 --> 37 --> 100101
              38 --> 38 --> 100110
              39 --> 39 --> 100111
              40 --> 40 --> 101000
              41 --> 41 --> 101001
              42 --> 42 --> 101010
              43 --> 43 --> 101011
              44 --> 44 --> 101100
              45 --> 45 --> 101101
              46 --> 46 --> 101110
              47 --> 47 --> 101111
              48 --> 48 --> 110000
              49 --> 49 --> 110001
              50 --> 50 --> 110010
              51 --> 51 --> 110011
              52 --> 52 --> 110100
              53 --> 53 --> 110101
              54 --> 54 --> 110110
              55 --> 55 --> 110111
              56 --> 56 --> 111000
              57 --> 57 --> 111001
              58 --> 58 --> 111010
              59 --> 59 --> 111011
              60 --> 60 --> 111100
              61 --> 61 --> 111101
              62 --> 62 --> 111110
              63 --> 63 --> 111111
              64 --> 64 --> 1000000
              65 --> 65 --> 1000001
              66 --> 66 --> 1000010
              67 --> 68 --> 1000100
              68 --> 69 --> 1000101
              69 --> 70 --> 1000110
              70 --> 71 --> 1000111
              71 --> 71 --> 1000111
              72 --> 72 --> 1001000
              73 --> 73 --> 1001001
              74 --> 74 --> 1001010
              75 --> 75 --> 1001011
              76 --> 76 --> 1001100
              77 --> 77 --> 1001101
              78 --> 78 --> 1001110
              79 --> 79 --> 1001111
              80 --> 80 --> 1010000
              81 --> 82 --> 1010010
              82 --> 83 --> 1010011
              83 --> 84 --> 1010100
              84 --> 85 --> 1010101
              85 --> 86 --> 1010110
              86 --> 87 --> 1010111
              87 --> 88 --> 1011000
              88 --> 89 --> 1011001
              89 --> 90 --> 1011010
              90 --> 91 --> 1011011
              91 --> 92 --> 1011100
              92 --> 93 --> 1011101
              93 --> 94 --> 1011110
              94 --> 95 --> 1011111
              95 --> 96 --> 1100000
              96 --> 97 --> 1100001
              97 --> 98 --> 1100010
              98 --> 99 --> 1100011
              99 --> 100 --> 1100100
              100 --> 101 --> 1100101
              101 --> 102 --> 1100110
              • 4. Re: Pixel Values are Chaning After IOImage.write operation
                843802
                Works for me?
                import javax.imageio.*;
                import java.awt.image.*;
                import java.io.*;
                
                public class SSCCE {
                    public static void main(String[] args) throws Exception{
                        BufferedImage before = new BufferedImage(10,10,
                                BufferedImage.TYPE_BYTE_GRAY);
                        byte[] imgDataBefore =
                                ((DataBufferByte) before.getRaster().getDataBuffer()).getData();
                
                        //fill image with random information
                        new java.util.Random().nextBytes(imgDataBefore);
                
                        //do some manipulation
                        for(int i = 0; i < imgDataBefore.length; i++) {
                            if(imgDataBefore%2==0)
                imgDataBefore[i] = (byte)(imgDataBefore[i] | 0x01);
                else if(imgDataBefore[i]==0)
                imgDataBefore[i] = (byte)1;
                else
                imgDataBefore[i] = (byte)(imgDataBefore[i] & 0xFE);
                }

                //write/read image
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                ImageIO.write(before,"png",out);

                BufferedImage after = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));

                byte[] imgDataAfter =
                ((DataBufferByte) after.getRaster().getDataBuffer()).getData();

                //compare before and after
                for(int i = 0; i < imgDataBefore.length; i++) {
                int beforeWrite = imgDataBefore[i] & 0xff;
                int afterWrite = imgDataAfter[i] & 0xff;

                System.out.print(beforeWrite + " " + afterWrite);
                if(beforeWrite != afterWrite)
                System.out.print(" Error!");
                System.out.println();
                }

                }
                }
                171 171
                20 20
                183 183
                95 95
                199 199
                222 222
                142 142
                186 186
                18 18
                122 122
                141 141
                240 240
                114 114
                62 62
                14 14
                38 38
                225 225
                136 136
                126 126
                254 254
                101 101
                232 232
                169 169
                86 86
                135 135
                204 204
                9 9
                159 159
                116 116
                119 119
                90 90
                27 27
                174 174
                181 181
                197 197
                140 140
                226 226
                8 8
                155 155
                184 184
                96 96
                120 120
                191 191
                171 171
                73 73
                235 235
                20 20
                178 178
                227 227
                212 212
                110 110
                206 206
                20 20
                20 20
                69 69
                115 115
                28 28
                20 20
                94 94
                117 117
                162 162
                70 70
                36 36
                84 84
                156 156
                223 223
                34 34
                179 179
                80 80
                144 144
                73 73
                14 14
                78 78
                112 112
                195 195
                26 26
                89 89
                117 117
                139 139
                178 178
                176 176
                164 164
                175 175
                9 9
                46 46
                118 118
                28 28
                116 116
                27 27
                86 86
                72 72
                94 94
                185 185
                223 223
                118 118
                64 64
                51 51
                140 140
                120 120
                138 138
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                • 5. Re: Pixel Values are Chaning After IOImage.write operation
                  843802
                  woww.. yeah.. your program infact works for me.. but what is the problem with my program.. will you please go through that once..
                  package stego;
                  
                  /**
                   *
                   * @author Srikant
                   */
                  import javax.swing.JFrame;
                  import javax.swing.JButton;
                  import java.awt.event.ActionListener;
                  import java.awt.event.ActionEvent;
                  import javax.swing.JLabel;
                  import javax.swing.UIManager;
                  import javax.swing.SwingUtilities;
                  import javax.swing.JTextField;
                  import java.awt.FileDialog;
                  
                  public class Main extends JFrame implements ActionListener
                  {
                  JLabel jl1, jl2, jl3, jl4;
                  JButton jb,b1,b2,b4,jb2;
                  JTextField jtf1,jtf2, jtf3, jtf4;
                  FileDialog fd1, fd2, fd4;
                  String str1,str2,str3,str4;
                  int Length,n[];
                  
                  Main()
                  {
                  str1=".null"; str2=".null"; str4=".null";
                  Length = 15;
                  setLayout(null);
                  jb=new JButton("OK");
                  jtf1=new JTextField(20);
                  jtf2=new JTextField(20);
                  jtf3=new JTextField(20);
                  jtf4=new JTextField(20);
                  b1=new JButton("Browse");
                  b2=new JButton("Browse");
                  b4=new JButton("Browse");
                  jb2=new JButton("Display");
                  jl1=new JLabel("Select a Text File: ");
                  jl2=new JLabel("Select an Image File: ");
                  jl3=new JLabel("Enter Name for Output File: ");
                  jl4=new JLabel("Select an Image File: ");
                  fd1=new FileDialog(this,"Open File", FileDialog.LOAD);
                  fd2=new FileDialog(this,"Open File", FileDialog.LOAD);
                  fd4=new FileDialog(this,"Open File", FileDialog.LOAD);
                  jb.addActionListener(this);
                  b1.addActionListener(this);
                  b2.addActionListener(this);
                  b4.addActionListener(this);
                  jb2.addActionListener(this);
                  add(jl1);
                  add(jtf1);
                  add(b1);
                  add(jl2);
                  add(jtf2);
                  add(b2);
                  add(jl3);
                  add(jtf3);
                  add(jb);
                  add(jl4);
                  add(jtf4);
                  add(b4);
                  add(jb2);
                  jl1.setBounds(25,25,150,20);
                  jtf1.setBounds(180,25,150,20);
                  b1.setBounds(350,25,90,20);
                  jl2.setBounds(25,100,150,20);
                  jtf2.setBounds(180,100,150,20);
                  b2.setBounds(350,100,90,20);
                  jl3.setBounds(25,180,150,20);
                  jtf3.setBounds(180,180,150,20);
                  jb.setBounds(25,250,60,20);
                  jl4.setBounds(25,300,150,20);
                  jtf4.setBounds(180,300,150,20);
                  b4.setBounds(350,300,90,20);
                  jb2.setBounds(25,350,90,20);
                  }
                  
                  
                  public void actionPerformed(ActionEvent ae)
                  {
                  if(ae.getSource()==b1)
                  {
                  fd1.setFile("*.txt");
                  fd1.setDirectory(".");
                  fd1.setVisible(true);
                  str1 = fd1.getDirectory()+fd1.getFile();
                  if(!str1.equals(".null"))
                  jtf1.setText(str1);
                  Length = 13;
                  }
                  else if(ae.getSource()==b2)
                  {
                  fd2.setFile("*.png");
                  fd2.setDirectory(".");
                  fd2.setVisible(true);
                  str2 = fd2.getDirectory()+fd2.getFile();
                  if(!str2.equals(".null"))
                  jtf2.setText(str2);
                  }
                  else if(ae.getSource()==b4)
                  {
                  fd4.setFile("*.png");
                  fd4.setDirectory(".");
                  fd4.setVisible(true);
                  str4 = fd4.getDirectory()+fd4.getFile();
                  if(!str4.equals(".null"))
                  jtf4.setText(str4);
                  System.out.println(str4);
                  }
                  else if(ae.getSource()==jb && !str2.equals(".null"))// && !str1.equals(".null"))
                  {
                  IOImage image = new IOImage();
                  int width = 0, height = 0;
                  try{
                  image.read(str2);
                  }catch(Exception e){
                  System.err.println(e.getMessage());
                  System.exit(1);
                  }
                  str3 = jtf3.getText();
                  if(str3.equals(".null") || str3.equals("")) str3 = "C:/Documents and Settings/Srikant/My Documents/My Stegos/mystego.png";
                  else str3 = "C:/Documents and Settings/Srikant/My Documents/My Stegos/" + str3 + ".png";
                  width = image.getWidth();
                  height = image.getHeight();
                  ImgSteg(str3,image);
                  System.out.println("\n*********\nStego Successful\n*********");
                  }
                  else if(ae.getSource()==jb2 && !str4.equals(".null"))// && !str1.equals(".null"))
                  {
                      System.out.println("Pixel value display");
                  IOImage image = new IOImage();
                  int x = 0, y = 0, width = 0, height = 0;
                  try{
                  image.read(str4);
                  }catch(Exception e){
                  System.err.println(e.toString());
                  System.exit(1);
                  }
                  
                  width = image.getWidth();
                  height = image.getHeight();
                  int i=0;
                  for(x = 0; x < width; x++)
                  {
                      for(y = 0; y < height; y++)
                      {
                          int m=new Integer(image.data).intValue();
                  n=new int[width*height];
                  if(m<0)
                  {
                  n[i] = image.data[i] & 0x80;
                  n[i] = n[i]+(image.data[i] & 0x7F);
                  }
                  else n[i] = (int) image.data[i];
                  System.out.println(i+" --> "+image.data[i]+" --> "+Integer.toBinaryString(n[i]));//+" --> "+n[i]+" --> "+(byte)n[i]);
                  i++;
                  }
                  }
                  }
                  }



                  private void ImgSteg(String ref, IOImage image)
                  {
                  for(int i =0; i< image.data.length ; i++)
                  {
                  if(image.data[i]%2==0) image.data[i] = (byte)(image.data[i] | 0x01);
                  else image.data[i] = (byte)(image.data[i] & 0xFE);
                  }


                  try {
                  image.write(image.image, ref);
                  } catch (Exception ex) {
                  System.out.println(ex.toString());
                  }
                  }

                  public static void main(String ar[])
                  {
                  Main s=new Main();
                  try{
                  UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel")
                  ;
                  SwingUtilities.updateComponentTreeUI(s);
                  }
                  catch(Exception e){}
                  s.setSize(600,500);
                  s.setVisible(true);
                  s.setTitle("Image Steganography by Mapping Pixels to Letters");
                  s.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  }

                  }
                  package stego;

                  import java.awt.color.ColorSpace;
                  import java.awt.image.BufferedImage;
                  import java.awt.image.ColorConvertOp;
                  import java.awt.image.DataBufferByte;
                  import java.io.File;
                  import java.io.IOException;
                  import javax.imageio.ImageIO;
                  import sun.awt.image.ImageFormatException;

                  /**
                  *
                  * @author Srikant
                  */
                  public class IOImage{

                  public BufferedImage img,image;
                  public byte[] data;

                  IOImage(){
                  }

                  public IOImage(int width, int height) {
                  image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
                  }

                  public void read(String filename)throws IOException, ImageFormatException{
                  img = ImageIO.read(new File(filename));
                  ColorConvertOp op = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
                  image = op.filter(img, null);
                  DataBufferByte buffer = (DataBufferByte) image.getRaster().getDataBuffer();
                  data = buffer.getData();
                  }
                  }
                  }

                  public void write(BufferedImage img1, String filename)throws IOException{
                  ImageIO.write(img1,"png",(new File(filename)));
                  }

                  public int getHeight() {
                  return image.getHeight();
                  }

                  public int getWidth() {
                  return image.getWidth();
                  }

                  public void setRGB(int x, int y, int pixel) {
                  image.setRGB(x,y,pixel);
                  }

                  }
                  here are the two java programs i wrote.. you need to place them in a single package.. go through that once and let me know my mistake please.. i want to know where i have gone wrong.. thanks a lot for your help..