Created
January 13, 2012 16:03
-
-
Save doskir/1607196 to your computer and use it in GitHub Desktop.
Image Steganography
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private Bitmap EmbeddStringIntoBitmap(Bitmap bmp,string s) | |
{ | |
//append a NULL terminator | |
s += '\0'; | |
//for now we only accept 32bit PNG files | |
if (bmp.PixelFormat != PixelFormat.Format32bppArgb) | |
throw new Exception(); | |
Bitmap stegBitmap = new Bitmap(bmp); | |
byte[] stringBytes = Encoding.ASCII.GetBytes(s); | |
BitArray bits = new BitArray(stringBytes); | |
if(bits.Length % 3 != 0) | |
{ | |
BitArray newBits = new BitArray(bits.Length + (3 - bits.Length%3)); | |
for(int i = 0;i < bits.Length;i++) | |
{ | |
newBits.Set(i, bits[i]); | |
} | |
bits = newBits; | |
} | |
int bitOffset = 0; | |
for(int y = 0; y < stegBitmap.Height;y++) | |
{ | |
if (bitOffset >= bits.Length) | |
break; | |
for(int x = 0;x < stegBitmap.Width;x++) | |
{ | |
if (bitOffset >= bits.Length) | |
break; | |
Color pixel = stegBitmap.GetPixel(x, y); | |
if (pixel.A != 255) | |
continue; | |
//set the least significant bit to 0 | |
int red = pixel.R & 254; | |
//set the least significant bit to one we want | |
red = red | (bits[bitOffset] ? 1 : 0); | |
int green = pixel.G & 254; | |
green = green | (bits[bitOffset+1] ? 1:0); | |
int blue = pixel.B & 254; | |
blue = blue | (bits[bitOffset + 2] ? 1 : 0); | |
bitOffset += 3; | |
Color newPixel = Color.FromArgb(pixel.A, red, green, blue); | |
stegBitmap.SetPixel(x, y, newPixel); | |
} | |
} | |
return stegBitmap; | |
} | |
private string RetrieveStringFromBitmap(Bitmap bmp) | |
{ | |
BitArray bits = new BitArray(bmp.Width*bmp.Height*3); | |
int bitOffset = 0; | |
for(int y = 0;y < bmp.Height;y++) | |
{ | |
for(int x = 0;x < bmp.Width;x++) | |
{ | |
Color pixel = bmp.GetPixel(x, y); | |
if (pixel.A != 255) | |
continue; | |
bool redBit = pixel.R%2==1; | |
bool greenBit = pixel.G%2 == 1; | |
bool blueBit = pixel.B%2 == 1; | |
bits[bitOffset] = redBit; | |
bits[bitOffset + 1] = greenBit; | |
bits[bitOffset + 2] = blueBit; | |
bitOffset += 3; | |
} | |
} | |
StringBuilder sb = new StringBuilder(); | |
for (int offset = 0; offset < bits.Length; ) | |
{ | |
byte b = (byte) (bits[offset] ? 1 : 0); | |
offset++; | |
for (; offset%8 != 0; offset++) | |
{ | |
int temp = 0; | |
//set the least significant bit to its respective bit in the bitarray | |
temp |= bits[offset] ? 1 : 0; | |
//left shift it to the correct position | |
temp <<= (offset%8); | |
//OR it with the data we already have to set the correct bit in the assembled byte | |
b = (byte) (b | temp); | |
} | |
char c = (char) b; | |
//we are checking for a null terminator to easily find the end of the text | |
if (c == '\0') | |
break; | |
sb.Append(c); | |
} | |
return sb.ToString(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment