I'm trying to resize some images with canvas but I'm clueless on how to smoothen them. On photoshop, browsers etc.. there are a few algorithms they use (e.g. bicubic, bilinear) but I don't know if these are built into canvas or not.
Here's my fiddle: http://jsfiddle.net/EWupT/
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width=300
canvas.height=234
ctx.drawImage(img, 0, 0, 300, 234);
document.body.appendChild(canvas);
The first one is a normal resized image tag, and the second one is canvas. Notice how the canvas one is not as smooth. How can I achieve 'smoothness'?
I created a library that allows you to downstep any percentage while keeping all the color data.
https://github.com/danschumann/limby-resize/blob/master/lib/canvas_resize.js
That file you can include in the browser. The results will look like photoshop or image magick, preserving all the color data, averaging pixels, rather than taking nearby ones and dropping others. It doesn't use a formula to guess the averages, it takes the exact average.
Since Trung Le Nguyen Nhat's fiddle isn't correct at all (it just uses the original image in the last step)
I wrote my own general fiddle with performance comparison:
FIDDLE
Basically it's:
I created a reusable Angular service to handle high quality resizing of images / canvases for anyone who's interested: https://gist.github.com/transitive-bullshit/37bac5e741eaec60e983
The service includes two solutions because they both have their own pros / cons. The lanczos convolution approach is higher quality at the cost of being slower, whereas the step-wise downscaling approach produces reasonably antialiased results and is significantly faster.
Example usage:
I wrote small js-utility to crop and resize image on front-end. Here is link on GitHub project. Also you can get blob from final image to send it.
Based on K3N answer, I rewrite code generally for anyone wants
UPDATE JSFIDDLE DEMO
Here is my ONLINE DEMO
You can use down-stepping to achieve better results. Most browsers seem to use linear interpolation rather than bi-cubic when resizing images.
(Update There has been added a quality property to the specs,
imageSmoothingQuality
which is currently available in Chrome only.)Unless one chooses no smoothing or nearest neighbor the browser will always interpolate the image after down-scaling it as this function as a low-pass filter to avoid aliasing.
Bi-linear uses 2x2 pixels to do the interpolation while bi-cubic uses 4x4 so by doing it in steps you can get close to bi-cubic result while using bi-linear interpolation as seen in the resulting images.
Depending on how drastic your resize is you can might skip step 2 if the difference is less.
In the demo you can see the new result is now much similar to the image element.