The post is a programming exercise from Duke’s course on Coursera as mentioned in previous posts:
Before you read my post, you can open Duke’s JavaScript Programming Environment, so you can test my codes. Link:
http://www.dukelearntoprogram.com/course1/example/index.php
Below is the instruction from the course material:
You should modify the steganography program you wrote earlier in this module to add a function named extract to extract the image that is hiding in the lower half of the 8 bits (lower 4 bits) for each RGB part of each pixel. The function extract has one parameter image, and it returns a new image, which is the image that was hidden in the lower half of the bits for each RGB part of each pixel.
– E.g., Suppose the red value of a pixel is 203. Convert that number to binary. 203 is 128 + 64 + 8 + 2 + 1 = 11001011 in binary. You need to move the lower four bits, 1011, to the upper four bits and clear out the lower four bits, to 10110000.
Original images:


We’ll hide the 2nd image in the 1st image.
The code below is what we have so far to create a combined image named “combinedimage”. There are three steps…
// STEP1: // crop two images to be the same size function crop(image,width,height){ var n = new SimpleImage(width,height); for(var p of image.values()){ var x = p.getX(); var y = p.getY(); if (x < width && y < height){ var np = n.getPixel(x,y); np.setRed(p.getRed()); np.setBlue(p.getBlue()); np.setGreen(p.getGreen()); } } return n; } var start = new SimpleImage("astrachan.jpg"); var hide = new SimpleImage("duvall.jpg"); var cropWidth = start.getWidth(); if (hide.getWidth() < cropWidth) { cropWidth = hide.getWidth(); } var cropHeight = start.getHeight(); if (hide.getHeight() < cropHeight) { cropHeight = hide.getHeight(); } startc = crop(start,cropWidth, cropHeight); hidec = crop(hide,cropWidth, cropHeight); print(startc); print(hidec); // STEP2: // steganography: hide image "hide" in image "start" function pixchange(pixval){ var x = Math.floor(pixval/16) * 16; return x; } function chop2hide(image){ for(var px of image.values()){ px.setRed(pixchange(px.getRed())); px.setGreen(pixchange(px.getGreen())); px.setBlue(pixchange(px.getBlue())); } return image; } function shift(im){ var nim = new SimpleImage(im.getWidth(), im.getHeight()); for(var px of im.values()){ var x = px.getX(); var y = px.getY(); var npx = nim.getPixel(x,y); npx.setRed(Math.floor(px.getRed()/16)); npx.setGreen(Math.floor(px.getGreen()/16)); npx.setBlue(Math.floor(px.getBlue()/16)); } return nim; } starts = chop2hide(startc); hides = shift(hidec); print(starts);print(hides);
// STEP3: // steganography: combine the above two images // Combine image "starts"&"hides" = hide image "hide" in "start" function newpv(va,vb){ var answer=va+vb; if (va+vb>255) print("error:RGB value cannot be greater than 255"); return answer; } function combine(a,b){ var n = new SimpleImage (a.getWidth(),a.getHeight()); for (var pa of a.values()){ var x = pa.getX(); var y = pa.getY(); var pb = b.getPixel (x,y); var np = n.getPixel (x,y); np.setRed(newpv(pa.getRed(),pb.getRed())); np.setGreen(newpv(pa.getGreen(),pb.getGreen())); np.setBlue(newpv(pa.getBlue(),pb.getBlue())); } return n; } combinedimage=combine(starts,hides); print(combinedimage);
Next, we will extract the hidden image from “starts”. So I wrote the following program and added it to the existing program (after all the codes above):
// extract the hidden image // e.g. extract 1011 from 11001011... // ...and make it 10110000 function pchange(n){ var value = (n-Math.floor(n/16)*16)*16; return value; } function extract(i){ for(var ip of i.values()){ ip.setRed(pchange(ip.getRed())); ip.setGreen(pchange(ip.getGreen())); ip.setBlue(pchange(ip.getBlue())); } return i; } hiddenimage = extract(combinedimage); print(hiddenimage);
Great. It worked.
Complete code:
Output images:
Hey, I’ve also completed this part of the course — but I am having trouble figuring out how to hide 2 bits. Any ideas?
LikeLike
Hi Clifton, the way I did it was to start with the pixchange function. You may also find the discussion board helpful: https://www.coursera.org/learn/duke-programming-web/discussions/9rMGu3MlEeWgtQq7brjg6Q?sort=createdAtDesc&page=1
LikeLike
And the code for that is in project 3: http://codepen.io/sheny/post/e-portfolio
LikeLike