Resize image with javascript canvas (smoothly)

javascript image resize library
javascript resize image before upload
resizing and cropping images with canvas
javascript resize image proportionally
html5 canvas resize image aspect ratio
html5 canvas drag, drop, and resize images
javascript resize image base64
resize image javascript w3schools

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'?

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.

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var img = new Image();

img.onload = function () {

    // set size proportional to image
    canvas.height = canvas.width * (img.height / img.width);

    // step 1 - resize to 50%
    var oc = document.createElement('canvas'),
        octx = oc.getContext('2d');

    oc.width = img.width * 0.5;
    oc.height = img.height * 0.5;
    octx.drawImage(img, 0, 0, oc.width, oc.height);

    // step 2
    octx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5);

    // step 3, resize to final size
    ctx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5,
    0, 0, canvas.width, canvas.height);
}
img.src = "//i.imgur.com/SHo6Fub.jpg";
<img src="//i.imgur.com/SHo6Fub.jpg" width="300" height="234">
<canvas id="canvas" width=300></canvas>

Resizing and Cropping Images with Canvas, Learn how to resize and crop images using JavaScript and the HTML5 Canvas element using controls, commonly seen in photo editing  Resizing an Image with Javascript is fairly simple. Let’s take an example of that: If you use this below example that shows to preview the of resizing an image. Create Html <input id="imageFile" name="imageFile" type="file" class="imageFile" accept="image/*" /> <input type="button" value="Resize Image" onclick="ResizeImage()"/> <br/> <img src="" id="preview" > <img src="" id="output"> Implement JavaScript Code

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:

img.onload = function() {
   var canvas = document.createElement('canvas'),
       ctx = canvas.getContext("2d"),
       oc = document.createElement('canvas'),
       octx = oc.getContext('2d');

   canvas.width = width; // destination canvas size
   canvas.height = canvas.width * img.height / img.width;

   var cur = {
     width: Math.floor(img.width * 0.5),
     height: Math.floor(img.height * 0.5)
   }

   oc.width = cur.width;
   oc.height = cur.height;

   octx.drawImage(img, 0, 0, cur.width, cur.height);

   while (cur.width * 0.5 > width) {
     cur = {
       width: Math.floor(cur.width * 0.5),
       height: Math.floor(cur.height * 0.5)
     };
     octx.drawImage(oc, 0, 0, cur.width * 2, cur.height * 2, 0, 0, cur.width, cur.height);
   }

   ctx.drawImage(oc, 0, 0, cur.width, cur.height, 0, 0, canvas.width, canvas.height);
}

How do I resize images and the image canvas?, When enlarging images, the default resizing algorithm will blur the value: A Boolean indicating whether to smooth scaled images or not. JavaScript. const canvas = document.getElementById('canvas'); const ctx = canvas. JavaScript Image Resize: Rescale images smoothly using HTML canvas objects. Recommend this page to a friend! MIT/X Consortium This object can rescale images smoothly using HTML canvas objects. It can take an image given the image object or a selector string of the image element to rescale.

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:

angular.module('demo').controller('ExampleCtrl', function (imageService) {
  // EXAMPLE USAGE
  // NOTE: it's bad practice to access the DOM inside a controller, 
  // but this is just to show the example usage.

  // resize by lanczos-sinc filter
  imageService.resize($('#myimg')[0], 256, 256)
    .then(function (resizedImage) {
      // do something with resized image
    })

  // resize by stepping down image size in increments of 2x
  imageService.resizeStep($('#myimg')[0], 256, 256)
    .then(function (resizedImage) {
      // do something with resized image
    })
})

reference, 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.  I use html5 canvas elements to resize images im my browser. It turns out that the quality is very low. I found this: Disable Interpolation when Scaling a <canvas> but it does not help to increase the quality.

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.

Resize image proportionally with CSS, Use the File API, drag and drop, and HTML5 canvas to allow for JavaScript resizing of images. As the Javascript is perhaps going to ignore the CSS try to set the canvas width & height in the javascript & CSS with for example, I want my canvas to have an width of 650px and height of 750px if your id is called canvas and also add width & height in the canvas tag. canvas.width = 650px; canvas.height = 750px;

Based on K3N answer, I rewrite code generally for anyone wants

var oc = document.createElement('canvas'), octx = oc.getContext('2d');
    oc.width = img.width;
    oc.height = img.height;
    octx.drawImage(img, 0, 0);
    while (oc.width * 0.5 > width) {
       oc.width *= 0.5;
       oc.height *= 0.5;
       octx.drawImage(oc, 0, 0, oc.width, oc.height);
    }
    oc.width = width;
    oc.height = oc.width * img.height / img.width;
    octx.drawImage(img, 0, 0, oc.width, oc.height);

UPDATE JSFIDDLE DEMO

Here is my ONLINE DEMO

CanvasRenderingContext2D.imageSmoothingEnabled, Resize image to 10×50 ➜. This is part of the Canvas, images and pixels tutorial. var sourceimage = document.querySelector('img');; var canvas = document. Resize images on client side, using plain JavaScript. Only 4KB minified and written in TypeScript. This script offers smooth resizing by using multiple down-scaling steps (depending on source- and target-dimensions) and sharpen after resizing. You can also convert (transparent) png or svg to jpg, or (transparent) svg to (transparent) png.

Resize an Image Using Canvas, Drag and Drop and the File API, "This product uses canvas and needs JavaScript and your browser doesn't Resizing on a canvas also means you discard or add pixels to the image. force a canvas to not smooth pixels by setting the imageSmoothingEnabled property of​  The imageSmoothingEnabled property of the CanvasRenderingContext2D interface, part of the Canvas API, determines whether scaled images are smoothed (true, default) or not (false). On getting the imageSmoothingEnabled property, the last value it was set to is returned. This property is useful for games and other apps that use pixel art.

Resize image to fixed size, initial image. In other cases basic canvas resizing gives better image quality result. Javascript. function filesChanged(files) { for (var i = 0; i < files.length; i++)​  What you have to do is use canvas to create a thumbnail, you can draw the image at a smaller size. Then you write it to a dataURL which I then saved in a text file. I created my own gallery that loads the images up and if not creates the thumbnail on the fly.

Canvas, images and pixels, Is there any way to resize shapes just by dragging and can be saved as image in the end? Which part of the documentation should I take a look at  j'essaie de redimensionner des images avec de la toile, mais je ne sais pas comment les lisser. Sur photoshop, navigateurs etc.. il y a quelques algorithmes qu'ils utilisent (par exemple bicubic, bilinear) mais je ne sais pas si ceux-ci sont construits en canvas ou non.

Comments
  • @steve heh, sometimes these things happen :) For images you can usually override this by setting a css BTW.
  • Ken, the first result worked great but when I change the images, you can see it being too blurry jsfiddle.net/kcHLG What can be done in this case and others?
  • @steve you can reduce the number of steps to just 1 or none (for some images this works fine). See also this answer which is similar to this but here I added a sharpen convolution to it so you can make the resulting image sharper after it has been downscaled.
  • @steve here is an modified fiddle with Bill using only one extra step: jsfiddle.net/AbdiasSoftware/kcHLG/1
  • @neaumusic the code is a continuation of OPs code. If you open the fiddle you'll see ctx being defined. I have inlined it here to avoid misunderstandings.
  • Most underrated answer ever seen.
  • Sorry about that - I had changed my github username. Just updated the link gist.github.com/transitive-bullshit/37bac5e741eaec60e983
  • I saw the word angular, I got that funny feeling
  • I would probably use webgl to resize now
  • This won't work : each time you resize the canvas, it will clear its context. You need 2 canvases. Here it's just the same as directly calling drawImage with the final dimensions.
  • Because It's not widely supported caniuse.com/#search=createImageBitmap
  • createImageBitmap is supported for 73% of all users. Depending on your use case, it may be good enough. It's just Safari that refuses to add support for it. I think it's worth mentioning as a possible solution.