HTML5 : Canvas Image Manipulation Tutorial

Today, I’m sharing with you a little on Image manipulation using Canvas. Since it’s already 2012, I figured it’s time to write more on my HTML5 stuff. As you already know by now, one of the most powerful and interactive element in html5 is none other than the Canvas. Rather, than blogging about theory of what html5 is and what’s the new tag blah blah…I’m just gonna make a simple project out of it – a straight forward implementation. So today’s tutorial, I will be covering the followings :-

  • Loading an image into the canvas
  • Image blurring effect – using an External Library (StackBlur.js)
  • Image rotation – pure html5 canvas programming
  • Little on CSS3  – a little on the border radius stuff, gradient stuff.
  • Slider element of HTML5. – pure html5 usage of input type=”range” (yes, No more JQueryUI and loading lots of js files – just for one slider)

First of you might wanna have a look at the demo I’ve prepared in advance here. You may also download the entire tutorial below.

HTML5 Tutorial 1 (2598 downloads)

Ok, first let’s look html code itself. Like all standard html5 page, the standard doctype must be declared prior to anything. Click on the button to load an image into the canvas which is the white box with rounded borders in the center of the html page. Try playing around with the sliders. Apply blur effect and the rotation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
	<!-- Date: 2011-12-31 -->
	<script type="text/javascript" src="lib/StackBlur.js"></script>
	<script>
		function triggerReady(){
			var btnLoadImage 	= document.getElementById('btnLoadImage');
			var blur_range 		= document.getElementById('blurRange');
			var rotation_range 	= document.getElementById('rotationRange');
			var canvas 		 = document.getElementById('canvas');
			var imageRefence = document.getElementById('imgSrc');
                        // The Canvas context governs the rendering of the canvas content itself. 
			var contxt = canvas.getContext('2d');
                        // Declaring an image Object.
			var img = new Image();
			img.width = 480;
			img.height = 320;
 
			btnLoadImage.onclick = function(){
				img.onload = function(){
				    clear();
				    contxt.drawImage(img, 0, 0, img.width, img.height);
				}
				img.src = 'images/ProfilePic.png';
				imageRefence.src = img.src;
			}
 
			blur_range.onchange = function(){
				processImageBlur( blur_range.value );
			}
 
			rotation_range.onchange = function(){
				processRotateImage( rotation_range.value );
			}
 
			function processImageBlur( value ){
                                // I use stackBlur.js for this refer to this site to know more on how to use and apply this.
                                // http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html
				stackBlurImage( "imgSrc", "canvas", value, false );
				rotation_range.value = 0;
			}
 
			function processRotateImage( value ){
				clear();
				contxt.save();
                                // Like all rotation, it needs a center pivot to refer to.
                                // For that we use translate and move the coordinate to the middle of the image
				contxt.translate(480/2, 320/2);
                                contxt.rotate(value * Math.PI / 180);
				// You need to reverse translate back the coordinate because, you still need to render the image from 0,0.
                                contxt.translate(-(480/2), -(320/2));
				contxt.drawImage(img, 0, 0, 480, 320);
				contxt.restore();
			}
 
			function clear(){
                                // Erase content of the canvas and refresh.
				contxt.clearRect(0, 0, 480, 320);
			}
		}
 
	</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div class="titleBar">
    <h1 class="label15Arial">Sample App With Canvas</h1>
</div>
<div class="borderContainer"></div>
<div class="controlsContainer">
    <label class="range1label">Blur Range</label> 
    <input id="blurRange" class="range1" max="100" min="0" step="1" type="range" value="0" /> 
    <label class="range2label">Rotation</label> 
    <input id="rotationRange" class="range2" max="359" min="0" step="1" type="range" value="0" />
    <center><input id="btnLoadImage" class="buttons" type="submit" value="Load Image..." /></center>
</div>
<div id="referenceData" hidden="true">
    <img id="imgSrc" />
</div>

Take a look how the canvas is implemented, just a simple and clean tag isn’t it sweet ? Notice, in canvas programming, you must always remember, to “represent” an object e.g. image in our case, everything must be done in data abstraction in the memory – then render to display. Like the case of rotation (see line 48).

  • The canvas content is cleared,
  • New angle is calculated,
  • The coordinates is translated
  • Image object is rotated in memory
  • Image object is redrawn into the canvas

Every time a rotation slider value is changed. Well, the rest you can read up and experiment more by tweaking my codes in the source to find out more. We now take a look at the CSS file. By the way, I generate my gradient here

/**************************** HTML 5 RESET **************************/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}
 
/**************************** HTML 5 RESET **************************/
.label15Arial {
	font-family:Arial;
	color:#fff;
	font-size:16pt;
	font-weight:bolder;
	text-shadow: #333 0 0 0;
	padding-top:10px;
	text-align:center;
}
 
.titleBar {
        // Here is the cool gradient stuff - use generator http://gradients.glrzad.com/
	background-image: linear-gradient(bottom, rgb(0,0,0) 58%, rgb(184,184,184) 80%, rgb(39,46,46) 94%);
	background-image: -o-linear-gradient(bottom, rgb(0,0,0) 58%, rgb(184,184,184) 80%, rgb(39,46,46) 94%);
	background-image: -moz-linear-gradient(bottom, rgb(0,0,0) 58%, rgb(184,184,184) 80%, rgb(39,46,46) 94%);
	background-image: -webkit-linear-gradient(bottom, rgb(0,0,0) 58%, rgb(184,184,184) 80%, rgb(39,46,46) 94%);
	background-image: -ms-linear-gradient(bottom, rgb(0,0,0) 58%, rgb(184,184,184) 80%, rgb(39,46,46) 94%);
	width:100%;
	height:45px;
}
 
.borderContainer {
	border:1px solid #c0c0c0;
	margin-left:auto;
	margin-right:auto;
	margin-top:15px;
	width:480px;
	height:320px;
	-moz-border-radius: 8px;
	border-radius: 8px;
}
 
.controlsContainer {
	border:1px solid #c0c0c0;
	margin-left:auto;
	margin-right:auto;
	margin-top:15px;
	width:480px;
	height:120px;
	-moz-border-radius: 8px;
	border-radius: 8px;
}
 
.range1 {
	margin-top:15px;
	width:280px;
	float:left;
}
 
.range1label {
	font-family:Arial;
	color:#000;
	font-size:14px;
	margin-top:15px;
	margin-left:15px;
	width:105px;
	font-weight:bolder;
	text-shadow: #333 0 0 0;
	float:left;
}
 
.range2 {
	margin-top:15px;
	width:280px;
	float:left;
}
 
.range2label {
	font-family:Arial;
	color:#000;
	font-size:14px;
	margin-top:15px;
	margin-left:15px;
	width:105px;
	font-weight:bolder;
	text-shadow: #333 0 0 0;
	float:left;
}
 
.buttons {
	-moz-border-radius: 6px;
	border-radius: 6px;
	width:300px;
	background:#fff;
	height:30px;
	margin-top:15px;
	color:#000;
}
 
#canvas {
        // Just two lines for cool border radius, no more IE hack or using Image, then abusing of divs 
	-moz-border-radius: 6px;
	border-radius: 6px;
}

Note of warning :Things you should know about canvas. For some apparent reason, try not to style / css width and height of the canvas element. Instead using the attribute of width and height on to the tag itself. Reason being, some browsers will render the content scale weirdly. This information is accurate to date of the post. This issue might be fix in near future.

That’s it for today sharing. Oh yeah and Happy New Year 2012.

Comments

comments

4 thoughts on “HTML5 : Canvas Image Manipulation Tutorial

  1. yes, you are right. but, if u shouldn’t stop there because of old browsers still active on web in general – it will take age before, you even step into html5. Instead, look at what you can do in platforms like mobile webapp, windows 8 apps and chrome webstore. they are all powered by html5. u can use those to improve your profile also. 😉

Leave a Reply

Your email address will not be published. Required fields are marked *