Image cropping & resizing with HTML Canvas now built-in to Jetendo CMS
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.
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.
Bookmark & Share
Previous Article
Popular tags on this blog
Performance |Most Popular Articles
- Mass virtual hosting security tip when using a reverse proxy to connect to other servers
- Solution for MariaDB Field 'xxx' doesn't have a default value
- How to lock Windows immediately upon smart card removal
- Stop using sleep mode with Windows Bitlocker for better security. Learn how to use hibernate in Windows 8.
- Is Google Public DNS actually better then your ISP?
- Planning a system to visually create responsive data-driven web page layouts & widgets in the Jetendo CMS browser interface
- Pros and Cons of CFML vs PHP and other languages
- Run Windows Guest in CentOS 6 Linux Host using Virtualbox 4 via the command line