C:\> Rostislav Persion's Projects

.:: Bitmap Pixel Data Embedding ::.
Store secret messages inside the pixels of a BMP or PNG file




This program allows the user to store text data inside of the pixels of an image. The text data is converted to a binary number string. Then it is stored in the pixels by setting the red color channel to either an even value or an odd value. Even represents a binary 1 and odd represents a binary 0. To convert an odd to even or even to odd, a 1 is added to the red channel in a pixel.



Here is a PNG file with an encoded message...





   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.Threading.Tasks;
   6:  using System.Drawing;
   7:   
   8:   
   9:   
  10:  namespace CodeRed
  11:  {
  12:      class Program
  13:      {
  14:   
  15:   
  16:   
  17:          static bool IsEven(int val)
  18:          {
  19:              bool ret = false;
  20:              if (((double)val / 2) == Math.Round((double)val / 2)) { ret = true; }
  21:              return ret;
  22:          }
  23:   
  24:   
  25:          static string BinToLetters(string bin)
  26:          {
  27:              string ret = "";
  28:   
  29:              for (int i = 0; i < bin.Length; i += 8)
  30:              {
  31:                  string byt = bin.Substring(i, 8);
  32:   
  33:                  int result = 0;
  34:   
  35:                  bool bit1 = false;
  36:                  bool bit2 = false;
  37:                  bool bit3 = false;
  38:                  bool bit4 = false;
  39:                  bool bit5 = false;
  40:                  bool bit6 = false;
  41:                  bool bit7 = false;
  42:                  bool bit8 = false;
  43:   
  44:                  if (byt.Substring(0, 1) == "1") { bit1 = true; }
  45:                  if (byt.Substring(0, 1) == "0") { bit1 = false; }
  46:                  if (byt.Substring(1, 1) == "1") { bit2 = true; }
  47:                  if (byt.Substring(1, 1) == "0") { bit2 = false; }
  48:                  if (byt.Substring(2, 1) == "1") { bit3 = true; }
  49:                  if (byt.Substring(2, 1) == "0") { bit3 = false; }
  50:                  if (byt.Substring(3, 1) == "1") { bit4 = true; }
  51:                  if (byt.Substring(3, 1) == "0") { bit4 = false; }
  52:                  if (byt.Substring(4, 1) == "1") { bit5 = true; }
  53:                  if (byt.Substring(4, 1) == "0") { bit5 = false; }
  54:                  if (byt.Substring(5, 1) == "1") { bit6 = true; }
  55:                  if (byt.Substring(5, 1) == "0") { bit6 = false; }
  56:                  if (byt.Substring(6, 1) == "1") { bit7 = true; }
  57:                  if (byt.Substring(6, 1) == "0") { bit7 = false; }
  58:                  if (byt.Substring(7, 1) == "1") { bit8 = true; }
  59:                  if (byt.Substring(7, 1) == "0") { bit8 = false; }
  60:   
  61:                  if (bit1 == true) { result += (int)Math.Pow(2, 7); }
  62:                  if (bit2 == true) { result += (int)Math.Pow(2, 6); }
  63:                  if (bit3 == true) { result += (int)Math.Pow(2, 5); }
  64:                  if (bit4 == true) { result += (int)Math.Pow(2, 4); }
  65:                  if (bit5 == true) { result += (int)Math.Pow(2, 3); }
  66:                  if (bit6 == true) { result += (int)Math.Pow(2, 2); }
  67:                  if (bit7 == true) { result += (int)Math.Pow(2, 1); }
  68:                  if (bit8 == true) { result += (int)Math.Pow(2, 0); }
  69:   
  70:                  ret += (char)result;
  71:              }
  72:              return ret;
  73:          }
  74:   
  75:   
  76:   
  77:          static string LettersToBin(string str)
  78:          {
  79:              string result = "";
  80:              foreach (char chr in str)
  81:              {
  82:                  result += Convert.ToString(chr, 2).PadLeft(8, '0');
  83:              }
  84:   
  85:              return result.Trim();
  86:          }
  87:   
  88:          static void Main(string[] args)
  89:          {
  90:   
  91:              while (true)
  92:              {
  93:   
  94:                  Console.Clear();
  95:                  Console.ForegroundColor = ConsoleColor.Red;
  96:                  Console.WriteLine("(c) 2016 - ROSTISLAV PERSION - BMP/PNG IMAGE EMBEDDER");
  97:                  Console.WriteLine();
  98:   
  99:                  Console.ForegroundColor = ConsoleColor.Green;
 100:   
 101:                  Console.Write("STORE [S] or DECODE [D] or QUIT [Q]: ");
 102:                  string inpt = Console.ReadLine().Trim().ToUpper();
 103:   
 104:                  if (inpt == "Q")
 105:                  {
 106:                      Environment.Exit(0);
 107:                  }
 108:   
 109:                  if (inpt == "S")
 110:                  {
 111:   
 112:   
 113:   
 114:                      // USER INPUT
 115:                      Console.WriteLine();
 116:                      Console.Write("SOURCE BMP/PNG FILE: ");
 117:                      string openfile = Console.ReadLine().Trim();
 118:                      Console.Write("DESTINATION BMP/PNG FILE: ");
 119:                      string openfile2 = Console.ReadLine().Trim();
 120:   
 121:                      // LOAD BITMAP
 122:                      Bitmap bmp1 = new Bitmap(openfile);
 123:   
 124:                      // USER INPUT 
 125:                      Console.Write("MESSAGE TO STORE (MAXIMUM CHARACTERS: " + (Math.Floor((double)(bmp1.Width * bmp1.Height) / 8) - 1).ToString() + "): ");
 126:                      string message = Console.ReadLine().Trim();
 127:                      string bin = LettersToBin(message + "|");
 128:   
 129:   
 130:   
 131:   
 132:                      
 133:   
 134:   
 135:   
 136:   
 137:                      // WILL IT FIT??
 138:                      if (((bmp1.Width * bmp1.Height) / 8) < (message.Length + 1)) { Console.WriteLine("ERROR: TOO MUCH DATA."); Console.ReadLine(); break; }
 139:   
 140:   
 141:                      // PREPARE IMAGE
 142:                      for (int y = 0; y < bmp1.Height; y++)
 143:                      {
 144:                          for (int x = 0; x < bmp1.Width; x++)
 145:                          {
 146:                              Color col1 = bmp1.GetPixel(x, y);
 147:                              int rr = col1.R;
 148:                              int gg = col1.G;
 149:                              int bb = col1.B;
 150:                              if (rr == 255) { rr = 254; }
 151:   
 152:                              Color col2 = Color.FromArgb(rr, gg, bb);
 153:                             
 154:                              bmp1.SetPixel(x, y, col2);
 155:                          }
 156:                      }
 157:   
 158:   
 159:                  
 160:   
 161:   
 162:                      int cnt = -1;
 163:   
 164:                      for (int y = 0; y < bmp1.Height; y++)
 165:                      {
 166:                          for (int x = 0; x < bmp1.Width; x++)
 167:                          {
 168:                              cnt++;
 169:   
 170:                              Color col = bmp1.GetPixel(x, y);
 171:                              Color newcol = Color.White;
 172:   
 173:                              if (cnt < bin.Length)
 174:                              {
 175:   
 176:                                  if (bin.Substring(cnt, 1) == "0") // odd
 177:                                  {
 178:                                      if (IsEven(col.R)) { newcol = col; newcol = Color.FromArgb(col.R + 1, col.G, col.B); } else { newcol = col; }
 179:                                  }
 180:                                  if (bin.Substring(cnt, 1) == "1") // even
 181:                                  {
 182:                                      if (IsEven(col.R)) { newcol = col; } else { newcol = col; newcol = Color.FromArgb(col.R + 1, col.G, col.B); }
 183:                                  }
 184:   
 185:                                  bmp1.SetPixel(x, y, newcol);
 186:   
 187:                              }
 188:   
 189:   
 190:                          }
 191:   
 192:   
 193:                      }
 194:   
 195:                      bmp1.Save(openfile2);
 196:   
 197:   
 198:                      Console.ForegroundColor = ConsoleColor.Yellow;
 199:                      Console.WriteLine();
 200:                      Console.WriteLine("OUTPUT FILE: " + openfile2 + "\n");
 201:                      Console.WriteLine("TEXT MESSAGE: " + message + "\n");
 202:                      Console.WriteLine("BINARY MESSAGE: " + bin + "\n");
 203:                      Console.WriteLine("IMAGE DATA HAS BEEN ENCODED." + "\n");
 204:   
 205:                      Console.ForegroundColor = ConsoleColor.White;
 206:                      Console.WriteLine();
 207:                      Console.WriteLine("PRESS ENTER TO GOT TO MAIN MENU...");
 208:                      Console.ReadLine();
 209:   
 210:                  }
 211:   
 212:   
 213:   
 214:   
 215:   
 216:   
 217:                  if (inpt == "D")
 218:                  {
 219:                      // USER INPUT
 220:                      Console.WriteLine();
 221:                      Console.Write("DECODE BMP/PNG FILE: ");
 222:                      string openfile = Console.ReadLine().Trim();
 223:   
 224:   
 225:                      // LOAD BITMAP
 226:                      Bitmap bmp1 = new Bitmap(openfile);
 227:   
 228:                      // FILE SIZE
 229:                      Console.Write("NUMBER OF CHARACTERS TO GET (MAX: " + Math.Floor((double)(bmp1.Width * bmp1.Height) / 8).ToString() + "): ");
 230:                      int numchars = Convert.ToInt32(Console.ReadLine().Trim());
 231:                      Console.WriteLine();
 232:   
 233:   
 234:                      // WILL IT FIT??
 235:                      if (numchars > Math.Floor((double)(bmp1.Width * bmp1.Height) / 8)) { Console.WriteLine("ERROR: NUMBER OF CGHARACTERS IS MORE THAN MAXIMUM."); Console.ReadLine(); break; }
 236:   
 237:   
 238:   
 239:   
 240:   
 241:                      string bin = "";
 242:                      int cnt = 0;
 243:   
 244:                      for (int y = 0; y < bmp1.Height; y++)
 245:                      {
 246:                          for (int x = 0; x < bmp1.Width; x++)
 247:                          {
 248:                              cnt++;
 249:   
 250:                              if (cnt <= (numchars * 8))
 251:                              {
 252:   
 253:                                  Color col = bmp1.GetPixel(x, y);
 254:                                  if (IsEven(col.R)) { bin += "1"; } else { bin += "0"; }
 255:                              }
 256:                          }
 257:                      }
 258:   
 259:                      Console.ForegroundColor = ConsoleColor.Yellow;
 260:   
 261:   
 262:                      
 263:   
 264:                      string msgout = BinToLetters(bin) + "|";
 265:                      msgout = msgout.Substring(0, msgout.IndexOf("|"));
 266:                      Console.WriteLine("MESSAGE: " + msgout);
 267:   
 268:                      Console.ForegroundColor = ConsoleColor.White;
 269:                      Console.WriteLine();
 270:                      Console.WriteLine("PRESS ENTER TO GO TO MAIN MENU...");
 271:                      Console.ReadLine();
 272:   
 273:   
 274:   
 275:                  }
 276:   
 277:   
 278:   
 279:   
 280:   
 281:   
 282:   
 283:   
 284:   
 285:              }
 286:   
 287:          }
 288:      }
 289:  }