|
Hiding Information in Pictures
This page lets you experiment with hiding information in the noise
of an image file. You can use a Java applet to replace the least significant
bits of an image with your own data. The applet displays the changes so
you can see the difference it may make.
How It Works
Every picture is made up of pixels and every pixel is represented
with a number. In many cases, the number is really made up of 3 numbers
representing the amount of red, green and blue in the pixel. These are
usually 8 bit values between 0 and 255. A red pixel might have the value
(255,0,0), a blue one might be (0,0,180), a purple one might be (240,0,250) and so on.
Another way to think of these values is as bits. Each pixel is represented
with 24 bits with 8 bits allocated to the three colors. A red pixel may
be (11111111,00000000,00000000), a blue one
may be (00000000,00000000,10110100) and so on.
The least significant bit is the right most one in this binary
notation. So 255=11111111 and the least significant bit is a 1. If you
change this bit, the value becomes 254=11111110.
This program groups these into bit planes. The least significant
bits for all of the red, green and blue values in all of the pixels is
the least significant bit plane. The next to least significant bit plane
is made up of the next to least significant bit planes. Etc.
You can store information in all of the different bit planes with this
software. It begins by putting the data in the least significant bit plane
and moves out. The pull-down menu lets you control how deep it will go.
In most cases, replacing the least significant bit will change nothing.
The difference between 254 and 255 or 140 and 141 is so small that your
eyes won't even pick it up. In many cases, replacing two or three planes
won't make a difference. The best place to see changes quickly is to look
at the sky or similar smooth part of the image.
Other Features
You can also use this applet to check out the least significant
bits of an image. If you pick the option "Focus on Least Significant Bits",
the least significant bits will become the most significant bits. The rest
will be thrown out.
If you want to look at the correlation between the least and most significant
bits, choose the option "Compare Most and Least Significant". This will
look at each color plane. If the most and least significant bits agree,
then it will store a maximum value (255) at this pixel. If they disagree,
then it will store a minimum value (0) at this pixel.
Strange Limits and Video Card Caveats
The Java applet world is not the best place to experiment with
subtle colors. Two major problems can limit the accuracy of the image.
The first is the video card of the computer you're using. If you set
it to a low precision, say 256 colors, then the subtle changes will never
appear. The card will be filtering them out by reducing the number of
colors to 256. If you want to play with this option, please use higher
precision video cards.
The applet can also be affected by the number of colors in the image.
Java loads GIF images, a format with only 256 colors, and JPEG images,
a so-called "lossy" format that doesn't reproduce images exactly. The
ideal format for this work is a 24-bit image which isn't supported.
Notice also how much information it takes to distort the image. You
can easily take over half of the image by inserting the data into the
four least significant bit planes. The distortion is minor. The intensitites
have changed +/- 15 units on a scale of 0 to 255. That's about 6% at most.
The catch is that all of this extra space is often squeezed out of
an image by compression functions. Only artists (always suspicious)
traffic in 24-bit images. The average person doesn't need that color
fidelity. This means that storing information in the least significant
bit is often impractical. F5 and JSTEG are better algorithms that work with the JPEG
file format.
Two copies of the applet should start in separate windows.
Here are the steps for using the applet:
- Wait for the image and the data to load. The two URLs pointing
to the image and the data will appear after they're loaded. One of the current
versions just stores random data. The other one uses the results
from http://www.wayner.org/ and it leaves stripes because ASCII text leaves
the top bit set to zero.
- Choose how many bit planes to replace.
- Push the button.
- When the job is done, there will be two images in the window.
(You can resize it to make all of them visible. The one on the left is the
original image. The right one is the result after mixing in the data.
Please let me know if you have any suggestions. I'll
be glad to roll good ideas into the source tree. Write me, p3@wayner.org,
if you have trouble.
If you want to experiment with this applet, you can write me for the source.
Or you can just read the HTML source for this document, grab the JAR file
and change the params. Write if you find anything interesting.
|