Cropping and Resizing with Canvas
On a project I’m currently working on, I came across an issue where I needed to crop and resize images on the front-end before saving the image to our database. I didn’t want to use a big JavaScript library that adds 50kb to our app just for uploading avatars, which is a pretty infrequent action.
We were uploading images, processing the images as data URIs on the front-end, and saving the data URIs directly into the database. This worked well enough, but our database has a 500kb limit on cell size, and storing 500kb images that are just being used as 150x150 pixel avatars seems like a bad idea, anyway. Additionally, I needed to crop image to be a square to fit in our oh-so-trendy circular avatar component.
I came up with the idea of drawing the uploaded image onto a canvas, scaled and cropped, and then pulling data URI.
My proof of concept looked like this:
See the Pen Crop and Resize Images with Canvas by Shaun Kelly (@6stringbeliever) on CodePen.
The key part of this is the cropImage()
function. It takes a data URI and a width and returns a promise that resolves to the cropped and resized data URI. If you’re using it with a file input element like in the example above, I’d highly recommend tossing an accepts="image/*"
attribute on the input because loading a non-image into an <img>
tag will fail silently. I try to catch this by doing a string check on the input data URI for an image type, but I’m not 100% certain that this will catch all possible errors.
Canvas has great support and this process is pretty quick. Under a second for even several MB image files. And while this example just centers the image and crops to a square, with a little more and different math, you can use the same concept to do all sorts of basic image manipulation.