Image cropping & resizing with HTML Canvas now built-in to Jetendo CMS

  Follow me: Follow Bruce Kirkpatrick by email subscription Bruce Kirkpatrick on Twitter Bruce Kirkpatrick on Facebook
Mon, Apr 29, 2013 at 8:30PM

There are ugly white margins in some of the images we get from third party data providers and we like to remove these margins before the user sees the images.  Several months ago, I wrote a PHP script that detects where the white margins ends and then crops/resizes the image.  I made this process happen when the images are first downloaded so that the user just downloads a static file of the cropped image and no further processing is necessary.

However, some data providers don't allow us to download all the images in bulk, and some of those images randomly change each day.   This makes it impossible to pre-generate a cached version of every image.  So our app generates the cropped images on the fly each request.

Dynamic requests can be expensive

A single user visiting a page of listing results can generate a few dozen extra requests of the PHP cropping & resizing script.   As you get more users, this could add up to hundreds or thousands of PHP requests in a brief amount of time. This could cause the server to become unresponsive or slow under high traffic conditions.  To avoid this, I rewrote the PHP script to use HTML canvas and javascript on the user's browser (client-side).  The <canvas> tag and associated javascript API allow you to access the individual pixels of images and do modifications on them.  The <canvas> tag is where you paint the end result.

Compatibility

The <canvas> tag works consistently on Internet Explorer 9+, Opera, Firefox and Chrome.  On Internet Explorer 8 and below, I just display the original unmodified image with an <img> tag.  Less then 10% of users are on IE7 or IE8 now, so I felt like this was an acceptable trade-off.

Security

One issue I had to deal with is that you can't modify image data from a remote domain due to security limitations in the current browsers.  To get around this, I implemented a forwarding proxy in nginx for images only so that I could return the images through our domain.  This is still more efficient then calling PHP and it fixes the security errors.  To make it more secure, only specific file types like jpg or gif are allowed by the nginx proxy.

Performance

It only takes about 5 milliseconds to crop each image and display it on canvas.  This doesn't include the time to download the image.

Here is an example URL.  The thumbnails for the listings are loading with the new javascript / canvas code through the nginx proxy.

http://www.mtncountryrealestate.com/z/_zcore-app/listing/search-form?method=index&searchId=2&zIndex=1

Canvas Image API vs PHP GD Library

I found that the API for canvas is actually simpler then PHP's image API.  It didn't take very long to learn how to do it, and the code was a bit shorter since the browser does a lot of things for you.

Summary

Now, I won't have to worry about our server having excessively high CPU/disk for image resizing/cropping as we get more sites.

If you have a performance concern in your web application, it may be worth considering if you can get the user's browser to do some of the work for you.  It may allow you to host the application on a less powerful server and consume less bandwidth.

Resources

I used w3schools's HTML canvas documentation for most of the work and found some examples on stackoverflow.

http://www.w3schools.com/html/html5_canvas.asp


Bookmark & Share



Popular tags on this blog

Performance |