4

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?

Becky
  • 5,467
  • 9
  • 40
  • 73
  • do you want to fill the whole 300 * 300 area? – Sushovan Apr 01 '15 at 20:10
  • Is this what you have in mind? http://stackoverflow.com/questions/21961839/simulation-background-size-cover-in-canvas/21961894#21961894 (this fills the entire canvas, not just scale the image to fit inside..) –  Apr 01 '15 at 20:35
  • @KenFyrstenberg: Not exactly. In my situation I'm allowing the user to upload an image and then I'll be using the above solution to scale and draw the image to a canvas. Upon submit I'm planning generate a pdf. My problem is, if a user access the website using a mobile device and uploads an image how do I maintain the image quality on the pdf? (Assuming the width of the pdf page is 840px and the placeholder for the uploaded image area is 300px) – Becky Apr 01 '15 at 20:38
  • @Beki a 300x380 pixel canvas will not allow you to do that. You have to set the proper size of the canvas in relation to DPI in your PDF, then scale down the canvas in the page using CSS to fit in with the screen. I can make an answer showing all these parts. –  Apr 01 '15 at 20:39
  • @KenFyrstenberg: It would be really amazing if you could do thart!! – Becky Apr 01 '15 at 20:43
  • @Beki ok, see if that helps. I didn't make a demo as that would require a PDF conversion to be useful, but it should be simple enough and straight forward. Let me know if something needs elaboration! –  Apr 01 '15 at 21:00
  • @Beki you should probably update the question with this aspect of it as it is not clear that you need this for PDF as-is. –  Apr 01 '15 at 21:01

2 Answers2

6

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.

1

You'll need to resize your source image. You will need to calculate the destination size of the image, then use a couple extra parameters during your draw.

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = 188;
var y = 30;
var width = 200;
var height = 137;
var imageObj = new Image();

imageObj.onload = function() {
  context.drawImage(imageObj, x, y, width, height);
};

imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
body {
  margin: 0px;
  padding: 0px;
}
<canvas id="myCanvas" width="578" height="200"></canvas>

Source: http://www.html5canvastutorials.com/tutorials/html5-canvas-image-size/

ThS
  • 4,597
  • 2
  • 15
  • 27
Barett
  • 5,826
  • 6
  • 51
  • 55
  • thanks. as per the example if I change `var width = 200*2;` and `var height = 137*2;`, why does the image show only half of the image? – Becky Apr 01 '15 at 19:40
  • @Beki That's a problem with the site. Use the same code on [jsfiddle](http://jsfiddle.net/3jk9eq04/2/) and it works. – halex Apr 01 '15 at 19:58