Alright, take a look at the two versions of Starry Night above. They look the same, right?
WRONG.
There’s a Shel Silverstein poem in one of them. It’s chilling out in the different red values of the pixels in the upper left hand corner on the second Starry Night. I love this method of hiding messages.
If you convert letters into numbers, you can use those to make pixel color changes that are pretty darn subtle. Then when you send your encoded image to anyone with the original, they can use Processing to pull the message out.
How to Assign Letters to Numbers
Ok, the two methods that make this a painful-but-not-excruciating process are charAt() and indexOf().
charAt() will get you the character at a particular position, or index, of a string.
For instance, if you have the string “Hello” assigned to the variable message, then message.charAt(0) will equal “H”, message.charAt(1) will equal “e”, message.charAt(2) will equal “l” and so on.
indexOf() is the inverse method—it’ll get you the position, or index, of a character within a string.
So message.indexOf(“H”) will equal 0, message.indexOf(“e”) will equal 1, message.indexOf(“l”) will equal 2. indexOf returns the first occurrence of the character, so keep that in mind when you use it. For our purposes, we’ll only have unique characters in the alphabet string, so it won’t matter.
With those two methods, we can loop through the secret message using charAt() and assign each character a number based on its position in the alphabet string called abc using indexOf().
Take a look at this code to see how it works:
How to Push those Numbers into Red Values
You can approach this different ways—I decided to just add the character numbers to the red values in a copy of the original image, and presto, that’s our encoded image. But you could manipulate the green and blue values too, or subtract, or do some other voodoo math. For simplicity though, I wrote it into red, and I’m sticking to it.
A quick note: we actually don’t want any important characters an index 0 because that’ll just result in the same color. In the complete script, I put a period at index 0 as a placeholder, and a space at index 1 so that Processing will still be able to spot it when it decodes the message.
Before running the script, you have to make sure the original image is in the Processing folder, and its name is plugged into the script. That’s “Starry Night.jpg” below.
Here’s the rundown.
*Fun disclaimer: Don’t save the image as a jpg. It throws the RGB values, and I have absolutely no idea why. Use pngs.
Since the poem is short, it only changes the first vertical line of pixels (and not many of them). No one is going to notice that unless they’re zoomed in and, you know, insanely observant.
A computer can spot the difference easily though.
How to Pull the Message Out
To run the decoder, you’ll need to have both the original image and the encoded one loaded in the Processing folder, and you’ll need to adjust the names in the script below.
As written, it won’t just look at the red values. It looks at the blue and green too. When it notes a difference between the RGB values in the two images, it takes the difference between them (subtracts the encoded number from the original) and stashes those into a list of integers. At the end, it takes that list of numbers and converts them back to letters using the same abc string we used to encode it in the first place.
Hop over to Gist for a copy/paste version of the encoder and decoder.
Thanks for the article post.Really thank you! Great.
LikeLiked by 2 people
sublime
LikeLiked by 1 person
> “Don’t save the image as a jpg. It throws the RGB values, and I have absolutely no idea why.”
Compression. That’s why. Although theres ways around it, JPG’s are generally compressed by default.
More info:
https://en.wikipedia.org/wiki/JPEG#JPEG_compression
LikeLiked by 2 people