JavaScript Practice: Extract a Hidden Image

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:

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:

Owen Astrachan faculty Computer Science studio headshot
Robert Duvall computer science faculty headshot

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);
 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);

// 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()){
 return image;
function shift(im){
 var nim = new SimpleImage(im.getWidth(), 
 for(var px of im.values()){
 var x = px.getX();
 var y = px.getY();
 var npx = nim.getPixel(x,y);
 return nim;

starts = chop2hide(startc);
hides = shift(hidec);
// 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);
    return n;

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()){
    return i;
hiddenimage = extract(combinedimage);

Great. It worked.

Complete code:


Output images:




3 thoughts

  1. Hey, I’ve also completed this part of the course — but I am having trouble figuring out how to hide 2 bits. Any ideas?


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s