HTML5 Image Effects – Emboss

HTML5 Image Effects – Emboss

0 40520
HTML5 Image Effects - Emboss

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 pretty difficult method, but I sure that you can repeat it. In our demo we can play with different images by adding a emboss effect to them, as well as we can ‘export’ our result on the image element (<img>).

Here are our demo and downloadable package:

Live Demo
download in package

Ok, download the example files and lets start coding !


Step 1. HTML Markup

This is markup of our demo page. Here it is:

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="https://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 &lt;CANVAS&gt;</p></td>
                    <td><p>Image Object &lt;IMG&gt;</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 contain 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 of 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 is required 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 pixels of original image, and after – will apply some transformation.


Live Demo
download in package

Conclusion

I hope that our demo looks fine. Today we have added new interesting effect to our html5 application – Emboss. I will be glad to see your thanks and comments. Good luck!

SIMILAR ARTICLES

Understanding Closures

0 21885

NO COMMENTS

Leave a Reply