Search code examples
htmlcanvasresampling

HTML5 canvas: is there a way to resize image with "nearest neighbour" resampling?


I have some JS that makes some manipulations with images. I want to have pixelart-like graphics, so I had to enlarge original images in graphics editor. But I think it'd be good idea to make all the manipulations with the small image and then enlarge it with html5 functionality. This will save bunch of processing time (because now my demo (warning: domain-name may cause some issues at work etc) loads extremely long in Firefox, for example). But when I try to resize the image, it gets resampled bicubically. How to make it resize image without resampling? Is there any crossbrowser solution?


Solution

  • image-rendering: -webkit-optimize-contrast; /* webkit */
    image-rendering: -moz-crisp-edges /* Firefox */
    

    http://phrogz.net/tmp/canvas_image_zoom.html can provide a fallback case using canvas and getImageData. In short:

    // Create an offscreen canvas, draw an image to it, and fetch the pixels
    var offtx = document.createElement('canvas').getContext('2d');
    offtx.drawImage(img1,0,0);
    var imgData = offtx.getImageData(0,0,img1.width,img1.height).data;
    
    // Draw the zoomed-up pixels to a different canvas context
    for (var x=0;x<img1.width;++x){
      for (var y=0;y<img1.height;++y){
        // Find the starting index in the one-dimensional image data
        var i = (y*img1.width + x)*4;
        var r = imgData[i  ];
        var g = imgData[i+1];
        var b = imgData[i+2];
        var a = imgData[i+3];
        ctx2.fillStyle = "rgba("+r+","+g+","+b+","+(a/255)+")";
        ctx2.fillRect(x*zoom,y*zoom,zoom,zoom);
      }
    }
    

    More: MDN docs on image-rendering