HTML5 Image Effects – Emboss
Here are our demo and downloadable packages:
Live Demodownload 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<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="utf-8" />
<title>HTML5 Image Effects - Emboss | Script Tutorials</title>
<link href="css/main.css" rel="stylesheet" type="text/css" />
<script src="https://www.google.com/jsapi"></script>
<script>
google.load("jquery", "1.7.1");
</script>
<script src="js/script.js"></script>
</head>
<body>
<header>
<h2>HTML5 Image Effects - Emboss</h2>
<a href="http://www.script-tutorials.com/html5-image-effects-emboss/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
</header>
<div id="container" class="container">
<table cellspacing=0>
<tr>
<td><p>Canvas Object <CANVAS></p></td>
<td><p>Image Object <IMG></p></td>
</tr>
<tr>
<td><canvas id="source" width="500" height="500"></canvas><div id="next" class="button">Next image</div></td>
<td><img id="img" src="images/button.png" /></td>
</tr>
<tr>
<td><div id="emboss" class="button">Apply Emboss Effect</div></td>
<td><div id="toImage" class="button">To Image</div></td>
</tr>
</table>
</div>
</body>
</html>
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 Demodownload 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!
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)





