Facebook Twitter Gplus LinkedIn RSS
 
 
Home » Blog » Cropping & Scaling Images with Canvas HTML5

Cropping & Scaling Images with Canvas HTML5

Published on March 18th, 2012

One of the most challenging things with developing my Demotivate zApp has been making sure the aspect ratio of the image is perfect regardless of whether the user is using an iPhone or an iPad in portrait or landscape mode. Considering people can import just about any sized image, it was important that we could scale, center, and crop a square image taken by the device’s camera or chosen from the photo gallery.

The first step is the create the html canvas anchor in your html page (like index.html):

<canvas id="pic" width="200" height="200"></canvas>

Then add the following to your js file:

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
function cropImage(id) {
  var canvas = document.getElementById(id);
  var context = canvas.getContext("2d");
  var imageObj = new Image();
  var pixelRatio = window.devicePixelRatio;
  context.scale(pixelRatio, pixelRatio);
    
  imageObj.onload = function() {
    var sourceX = 0;
    var sourceY = 0;
    var destX = 0;
    var destY = 0;
        
  if (canvas.width > canvas.height) {
    var stretchRatio = ( imageObj.width / canvas.width );
    var sourceWidth = Math.floor(imageObj.width);
    var sourceHeight = Math.floor(canvas.height*stretchRatio);
    sourceY = Math.floor((imageObj.height - sourceHeight)/2);
  } else {
    var stretchRatio = ( imageObj.height / canvas.height );
    var sourceWidth = Math.floor(canvas.width*stretchRatio);
    var sourceHeight = Math.floor(imageObj.height);
    sourceX = Math.floor((imageObj.width - sourceWidth)/2);
  }            
  var destWidth = Math.floor(canvas.width / pixelRatio);
  var destHeight = Math.floor(canvas.height / pixelRatio);
                
  context.drawImage(imageObj, sourceX, sourceY, sourceWidth, 
        sourceHeight, destX, destY, destWidth, destHeight);
  };
  imageObj.src = 'PATH_TO_IMAGE';
}
function cropImage(id) {
  var canvas = document.getElementById(id);
  var context = canvas.getContext("2d");
  var imageObj = new Image();
  var pixelRatio = window.devicePixelRatio;
  context.scale(pixelRatio, pixelRatio);
    
  imageObj.onload = function() {
    var sourceX = 0;
    var sourceY = 0;
    var destX = 0;
    var destY = 0;
        
  if (canvas.width > canvas.height) {
    var stretchRatio = ( imageObj.width / canvas.width );
    var sourceWidth = Math.floor(imageObj.width);
    var sourceHeight = Math.floor(canvas.height*stretchRatio);
    sourceY = Math.floor((imageObj.height - sourceHeight)/2);
  } else {
    var stretchRatio = ( imageObj.height / canvas.height );
    var sourceWidth = Math.floor(canvas.width*stretchRatio);
    var sourceHeight = Math.floor(imageObj.height);
    sourceX = Math.floor((imageObj.width - sourceWidth)/2);
  }            
  var destWidth = Math.floor(canvas.width / pixelRatio);
  var destHeight = Math.floor(canvas.height / pixelRatio);
                
  context.drawImage(imageObj, sourceX, sourceY, sourceWidth, 
        sourceHeight, destX, destY, destWidth, destHeight);
  };
  imageObj.src = 'PATH_TO_IMAGE';
}

Now everything is as simple as calling your new javascript function:

cropImage('pic');

Here is an example image:

And after it is run through the script:

If the above frame looks blank, it is because you need to use a web-kit enabled browser like Chrome or Safari (basically not IE or Firefox).

Click here to view the code or right-click to save.

About the Author: Sprawl

Stephen Russell is a Mobile App developer and all around IT geek that spends his days running data centers and his nights coding. This site is the go to place for all of zSprawl's work and the infamous development blog. In his free time, he enjoys tinkering with web code, playing video games, and otherwise plotting to take over the Internets.

 

2 Responses to “Cropping & Scaling Images with Canvas HTML5”

  1. Serious enthusiast of this website, lots of your blog posts have seriously helped me out. Awaiting updates!

  2. Thanks for this great post and for helping me understand image scaling in a canvas. There is a bug which prevents it from working tall images. Here’s a fixed version:

    //Tall Original Image
    if (imageObj.height > imageObj.width) {
    var stretchRatio = ( imageObj.width / canvas.width );
    var sourceWidth = Math.floor(imageObj.width);
    var sourceHeight = Math.floor(canvas.height*stretchRatio);
    sourceY = Math.floor((imageObj.height – sourceHeight)/2);
    //Wide Original Image
    } else {
    var stretchRatio = ( imageObj.height / canvas.height );
    var sourceWidth = Math.floor(canvas.width*stretchRatio);
    var sourceHeight = Math.floor(imageObj.height);
    sourceX = Math.floor((imageObj.width – sourceWidth)/2);
    }

    var destWidth = Math.floor(canvas.width / pixelRatio);
    var destHeight = Math.floor(canvas.height / pixelRatio);

    context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);

Leave a Reply

© 2012 zSprawl's zApps