# 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:

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){
if (va+vb>255) print("error:RGB value cannot be greater than 255");
}
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:   ## 3 thoughts

1. Clifton says:

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

Like