Search code examples
javascripthtmlcanvas

Using drawImage() to output fixed size images on a canvas?


How do I use drawImage() to output full size images on a 300px X 380px canvas regardless of the source image size?

Example:

1). If there is a image of 75px X 95px I want to be able to draw it to fit a 300px X 380px canvas.

2). If there is a image of 1500px X 1900px I want to be able to draw it to fit a 300px X 380px canvas.

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("myPic");
ctx.drawImage(img,10,10);

What options are available to prevent any quality loss?


Solution

  • To scale the image to fit is not so hard, just use simple aspect ratio with the sizes:

    var ratioX = canvas.width / image.naturalWidth;
    var ratioY = canvas.height / image.naturalHeight;
    var ratio = Math.min(ratioX, ratioY);
    
    ctx.drawImage(image, 0, 0, image.naturalWidth * ratio, image.naturalHeight * ratio);
    

    To maintain quality; a canvas of 300x380 will either appear very tiny on print, or very blurry.

    It's important to keep the data from it in the target resolution. To do this, calculate the size using the target DPI (or rather, PPI). You will also need to know in advance what size the 300x380 area represents (e.g. in either inches, centimeters, millimeters etc.).

    For example:

    If the target PDF will have a PPI of 300, and the canvas represents 3 x 3.8 cm (just to keep it simple), then the width and height in pixel will be:

    var w = (3 / 2.54) * 300;   // cm -> inch x PPI
    var h = (3.8 / 2.54) * 300;
    

    Use this size on canvas' bitmap, then scale down the element using CSS:

    canvas.width = w|0;             // actual bitmap size, |0 cuts fractions
    canvas.height = h|0;
    canvas.style.width = "300px";   // size in pixel for screen use
    canvas.style.height = "380px";
    

    You can now use the canvas directly as an image source for the PDF while keeping print quality for the PDF (have in mind though, small images uploaded will not provide high print quality in any case).

    And of course, set the canvas size first, then use the code at top to draw in the image.