HTML5 Image Effects – Emboss
Today we continue our HTML5 canvas image filter examples. Today I would like to share with you a method of applying a Emboss effect to images. This is a pretty difficult method, but I am sure that you can repeat it. In our demo we can play with different images by adding an emboss effect to them, and we can ‘export’ our result on the image element (). Here are our demo and downloadable packages: Live Demo download in package Ok, download the example files and let's start coding ! Step 1. HTML Markup This is the markup of our demo page: index.html HTML5 Image Effects - Emboss Back to original tutorial on Script Tutorials Canvas Object Image Object Next imageApply Emboss EffectTo Image Basically – it contains just one canvas object, one image, and three ‘buttons’ (div elements). Step 2. CSS Here are our stylesheets (not so important, but anyway): css/main.css *{ margin:0; padding:0; } body { background-image:url(../images/bg.png); color:#fff; font:14px/1.3 Arial,sans-serif; } header { background-color:#212121; box-shadow: 0 -1px 2px #111111; display:block; height:70px; position:relative; width:100%; z-index:100; } header h2{ font-size:22px; font-weight:normal; left:50%; margin-left:-400px; padding:22px 0; position:absolute; width:540px; } header a.stuts,a.stuts:visited { border:none; text-decoration:none; color:#fcfcfc; font-size:14px; left:50%; line-height:31px; margin:23px 0 0 110px; position:absolute; top:0; } header .stuts span { font-size:22px; font-weight:bold; margin-left:5px; } .container { color: #000000; margin: 20px auto; overflow: hidden; position: relative; width: 1005px; } table { background-color: rgba(255, 255, 255, 0.7); } table td { border: 1px inset #888888; position: relative; text-align: center; } table td p { display: block; padding: 10px 0; } .button { cursor: pointer; height: 20px; padding: 15px 0; position: relative; text-align: center; width: 500px; -moz-user-select: none; -khtml-user-select: none; user-select: none; } Step 3. JS Finally – our JavaScript code for the Emboss effect: js/script.js // variables var canvas, ctx; var imgObj; // filter strength var strength = 0.5; // shifting matrix var matrix = [-2, -1, 0, -1, 1, 1, 0, 1, 2]; // normalize matrix function normalizeMatrix(m) { var j = 0; for (var i = 0; i < m.length; i++) { j += m[i]; } for (var i = 0; i < m.length; i++) { m[i] /= j; } return m; } // convert x-y coordinates into pixel position function convertCoordinates(x, y, w) { return x + (y * w); } // find a specified distance between two colours function findColorDiff(dif, dest, src) { return dif * dest + (1 - dif) * src; } // transform matrix function transformMatrix(img, pixels) { // create a second canvas and context to keep temp results var canvas2 = document.createElement('canvas'); var ctx2 = canvas2.getContext('2d'); ctx2.width = canvas2.width = img.width; ctx2.height = canvas2.height = img.height; // draw image ctx2.drawImage(img, 0, 0, img.width , img.height); var buffImageData = ctx2.getImageData(0, 0, canvas.width, canvas.height); var data = pixels.data; var bufferedData = buffImageData.data; // normalize matrix matrix = normalizeMatrix(matrix); var mSize = Math.sqrt(matrix.length); for (var i = 1; i < img.width - 1; i++) { for (var j = 1; j < img.height - 1; j++) { var sumR = sumG = sumB = 0; // loop through the matrix for (var h = 0; h < mSize; h++) { for (var w = 0; w < mSize; w++) { var r = convertCoordinates(i + h - 1, j + w - 1, img.width) << 2; // RGB for current pixel var currentPixel = { r: bufferedData[r], g: bufferedData[r + 1], b: bufferedData[r + 2] }; sumR += currentPixel.r * matrix[w + h * mSize]; sumG += currentPixel.g * matrix[w + h * mSize]; sumB += currentPixel.b * matrix[w + h * mSize]; } } var rf = convertCoordinates(i, j, img.width) << 2; data[rf] = findColorDiff(strength, sumR, data[rf]); data[rf + 1] = findColorDiff(strength, sumG, data[rf + 1]); data[rf + 2] = findColorDiff(strength, sumB, data[rf + 2]); } } return pixels; } // process emboss function function processEmboss() { // clear context ctx.clearRect(0, 0, canvas.width, canvas.height); // draw image ctx.drawImage(imgObj, 0, 0, imgObj.width , imgObj.height); // get image data var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); // transform image data imageData = transformMatrix(imgObj, imageData); // draw data back ctx.putImageData(imageData, 0, 0); }; $(function () { // create canvas and context objects canvas = document.getElementById('source'); ctx = canvas.getContext('2d'); // load source image imgObj = new Image(); imgObj.onload = function () { // draw image ctx.drawImage(this, 0, 0, this.width, this.height, 0, 0, canvas.width, canvas.height); } imgObj.src="images/pic1.jpg"; // different onclick handlers var iCur = 1; $('#next').click(function () { iCur++; if (iCur > 6) iCur = 1; imgObj.src="images/pic" + iCur + '.jpg'; }); $('#emboss').click(function () { processEmboss(); }); $('#toImage').click(function () { $('#img').attr('src', canvas.toDataURL('image/jpeg')); }); }); This effect requires some pretty difficult matrix transformations, so you can try to understand it, or use it as-is. Of course, our script will pass through all the pixels of the original image, and then will apply some transformations. Live Demo download in package Conclusion I hope that our demo looks fine. Today we have added a new interesting effect to our html5 application – Emboss. I will be glad to see your thanks and comments. Good luck!
March 20, 2012
·
13,181 Views