Build a Image Steganography Project to Hide Text in Images in HTML5 & Vanilla Javascript Full Project For Beginners

 

 

index.html

 

 

<div class="wrap">
	<h1>Vanilla JavaScript Steganography</h1>
	<h5><a target="_blank" href="https://github.com/caleboleary">Caleb O'Leary</a></h5>
	<h6>Thanks to <a target="_blank" href="https://github.com/steveosoule">Steven Soule</a> for some suggested edits</h6>
	<h4>From Wikipedia - 'Steganography is the practice of concealing a file, message, image, or video within another file, message, image, or video.'</h4>
	<p>This tool creates a canvas with your image, and an identically sized canvas with your text. It then searches through each pixel of the text canvas, if it sees black, it knows the pixel it's viewing is part of the message. It will find the pixel at the same point in your image canvas, and make sure that the green value of the RGB ends in a 7. If it sees white or transparent, it knows that it's not on the text, and will make sure the identically located pixel on your image canvas's green value does NOT end in 7. After this has been performed on the whole image, we now have an image where every pixel's green value does NOT end in a 7, except where it will spell a message. The decode function reverses this, it looks through the pixels of the uploaded image, and hides any pixel where it doesn't find a green value ending in 7. It's important to note that not all steganography is the same, there are other tools out there that use the alpha chanel, where we're affecting the green channel here. Images encoded with this tool should only be decoded by this tool, etc.</p>

	<h2>Encode an image with a message</h2>
	<label>Enter a message to hide within the image:</label><br/>
	<input type="password" id="message" placeholder="Enter your secret message"></br>
	<label>Upload an image image:</label><br/>
	<input type="file" id="imageLoader" name="imageLoader"/>
	<canvas id="imageCanvas"></canvas>
	<canvas id="textCanvas"></canvas>
	<hr>
	<h2>Decode an image</h2>
	<label>Upload an image:</label><br/>
	<input type="file" id="imageLoader2" name="imageLoader2"/>
	<canvas id="imageCanvas2"></canvas>
</div>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/foundation/6.2.0/foundation.min.css"/>

<style>

#textCanvas {
  display:none;
}

.wrap {
  padding:30px;
}

p {
  background-color:#ddd;
  padding:20px;
  border:1px solid #ccc;
}

</style>


<script>

var imageLoader = document.getElementById('imageLoader');
    imageLoader.addEventListener('change', handleImage, false);
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d');
var messageInput = document.getElementById('message');

var textCanvas = document.getElementById('textCanvas');
var tctx = textCanvas.getContext('2d');

//handle decoding
var decodeCanvas = document.getElementById('imageCanvas2');
var dctx = decodeCanvas.getContext('2d');
var imageLoader2 = document.getElementById('imageLoader2');
    imageLoader2.addEventListener('change', handleImage2, false);

function handleImage(e){
    var reader = new FileReader();
    reader.onload = function(event){
        var img = new Image();
        img.onload = function(){
            canvas.width = img.width;
            canvas.height = img.height;
            textCanvas.width=img.width;
            textCanvas.height=img.height;
            tctx.font = "30px Arial";
      var messageText = (messageInput.value.length) ? messageInput.value : 'Hello';
            tctx.fillText(messageText,10,50);
            ctx.drawImage(img,0,0);
            var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
            var textData = tctx.getImageData(0, 0, canvas.width, canvas.height);
            var pixelsInMsg = 0;
                pixelsOutMsg = 0;
            for (var i = 0; i < textData.data.length; i += 4) {
                if (textData.data[i+3] !== 0) {
                    if (imgData.data[i+1]%10 == 7) {
                        //do nothing, we're good
                    }
                    else if (imgData.data[i+1] > 247) {
                        imgData.data[i+1] = 247;
                    }
                    else {
                        while (imgData.data[i+1] % 10 != 7) {
                            imgData.data[i+1]++;
                        }
                    }
                    pixelsInMsg++;
                }
                else {
                    if (imgData.data[i+1]%10 == 7) {
                        imgData.data[i+1]--;
                    }
                    pixelsOutMsg++;
                }
            }
            console.log('pixels within message borders: '+pixelsInMsg);
            console.log('pixels outside of message borders: '+pixelsOutMsg);
            ctx.putImageData(imgData, 0, 0);
        };
        img.src = event.target.result;
    };
    reader.readAsDataURL(e.target.files[0]);
}

function handleImage2(e){
    console.log('handle image 2');
    var reader2 = new FileReader();
    reader2.onload = function(event){
        console.log('reader2 loaded');
        var img2 = new Image();
        img2.onload = function(){
            console.log('img2 loaded');
            decodeCanvas.width = img2.width;
            decodeCanvas.height = img2.height;
            dctx.drawImage(img2,0,0);
            var decodeData = dctx.getImageData(0, 0, decodeCanvas.width, decodeCanvas.height);
            for (var i = 0; i < decodeData.data.length; i += 4) {
                if (decodeData.data[i+1] % 10 == 7) {
                    decodeData.data[i] = 0;
                    decodeData.data[i+1] = 0;
                    decodeData.data[i+2] = 0;
                    decodeData.data[i+3] = 255;
                }
                else {
                    decodeData.data[i+3] = 0;
                }
            }
            dctx.putImageData(decodeData, 0, 0);
        };
        img2.src = event.target.result;
    };
    reader2.readAsDataURL(e.target.files[0]);
}

</script>

Leave a Reply