fork download
  1. import java.awt.Color;
  2. import java.awt.image.BufferedImage;
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.util.Scanner;
  6.  
  7. import javax.imageio.ImageIO;
  8.  
  9. public class EncodeBMP {
  10.  
  11. public static void main(String[] args) throws IOException {
  12. {
  13. BufferedImage bi = ImageIO.read(new File("in.bmp"));
  14. Color[][] image = new Color[bi.getWidth()][bi.getHeight()];
  15. for (int i = 0; i < image.length; i++)
  16. for (int j = 0; j < image[i].length; j++) {
  17. image[i][j] = new Color(bi.getRGB(i, j));
  18. }
  19. encodeBMP(image, "data");
  20. for (int i = 0; i < image.length; i++)
  21. for (int j = 0; j < image[i].length; j++) {
  22. bi.setRGB(i, j, image[i][j].getRGB());
  23. }
  24. ImageIO.write(bi, "bmp", new File("out.bmp"));
  25. }
  26. {
  27. BufferedImage bi = ImageIO.read(new File("out.bmp"));
  28. Color[][] image = new Color[bi.getWidth()][bi.getHeight()];
  29. for (int i = 0; i < image.length; i++)
  30. for (int j = 0; j < image[i].length; j++) {
  31. image[i][j] = new Color(bi.getRGB(i, j));
  32. }
  33. System.out.println(extractMessage(image));
  34. System.out.println("--------------------");
  35. }
  36. }
  37.  
  38. // returns byte with last bit modified if necessary
  39. private static void modLSB(int[] bytes, int j, char foo) {
  40. if (foo == '1')
  41. bytes[j] = bytes[j] | 1; // make lsb one
  42. else
  43. bytes[j] = bytes[j] & ~1; // make lsb zero
  44. }
  45.  
  46. // loads a text file and inserts it into the current BMP object
  47. public static void encodeBMP(Color[][] image, String fName) {
  48. String message = "";
  49. try {
  50. Scanner sc = new Scanner(new File(fName));
  51. while (sc.hasNextLine())
  52. message += sc.nextLine() + "\n";
  53. System.out.println(message);
  54. System.out.println("--------------------");
  55. sc.close();
  56.  
  57. // read all rgb values into a bytes array
  58. int[] bytes = new int[image.length * image[0].length * 3];
  59. int i = 0;
  60. for (Color[] cRow : image)
  61. for (Color c : cRow) {
  62. bytes[i++] = c.getRed();
  63. bytes[i++] = c.getGreen();
  64. bytes[i++] = c.getBlue();
  65. }
  66.  
  67. // modify each value based on the text
  68. int j = 0;
  69. for (i = 0; i < message.length(); i++) {
  70. char c = message.charAt(i);
  71. String bin = Integer.toBinaryString((int) c);
  72. bin = eightBitsLong(bin);
  73.  
  74. modLSB(bytes, j++, bin.charAt(0));
  75. modLSB(bytes, j++, bin.charAt(1));
  76. modLSB(bytes, j++, bin.charAt(2));
  77. modLSB(bytes, j++, bin.charAt(3));
  78. modLSB(bytes, j++, bin.charAt(4));
  79. modLSB(bytes, j++, bin.charAt(5));
  80. modLSB(bytes, j++, bin.charAt(6));
  81. modLSB(bytes, j++, bin.charAt(7));
  82. }
  83.  
  84. // read values back into colors
  85. int k = 0;
  86. for (i = 0; i < image.length; i++)
  87. for (j = 0; j < image[i].length; j++) {
  88. image[i][j] = new Color(bytes[k], bytes[k + 1],
  89. bytes[k + 2]);
  90. k += 3;
  91. }
  92. } catch (Exception e) {
  93. e.printStackTrace();
  94. System.exit(0);
  95. }
  96. }
  97.  
  98. private static String eightBitsLong(String str) // recursion!
  99. {
  100. if (str.length() == 8)
  101. return str;
  102. else if (str.length() > 8)
  103. return eightBitsLong(str.substring(2));
  104. else
  105. return eightBitsLong("0" + str);
  106. }
  107.  
  108. // extracts a message hidden in a BMP file
  109. public static String extractMessage(Color[][] image) {
  110. int iter = 0;
  111. // read the lsbs of the rgb values into one array
  112. char[] pixels = new char[image.length * image[0].length * 3];
  113. for (Color[] cRow : image)
  114. for (Color c : cRow) {
  115. pixels[iter++] = (char) (c.getRed() & 1); // make zero or one
  116. pixels[iter++] = (char) (c.getGreen() & 1);
  117. pixels[iter++] = (char) (c.getBlue() & 1);
  118. }
  119.  
  120. // iterate through the pixels and move the lsbs into the correct place
  121. // value
  122. String message = "";
  123. int i = 0;
  124. while (i < pixels.length - pixels.length % 8) {
  125. char c = (char) 0;
  126. c += pixels[i++] << 7; // 1
  127. c += pixels[i++] << 6; // 2
  128. c += pixels[i++] << 5; // 3
  129. c += pixels[i++] << 4; // 4
  130. c += pixels[i++] << 3; // 5
  131. c += pixels[i++] << 2; // 6
  132. c += pixels[i++] << 1; // 7
  133. c += pixels[i++]; // 8
  134. message += c;
  135. }
  136. return message;
  137. }
  138.  
  139. }
  140.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty