5

I'm trying to load an image from a URL into a HTML canvas at a 1:1 scale. I load the image, and set the canvas DOM element to the appropriate dimensions, but for some reason the image in the canvas is significantly upscaled and therefore only the top left hand corner is drawn.

This is demonstrated by the following JSFiddle: http://jsfiddle.net/KdrYr/1/

var img = new Image();
var cv = document.getElementById('thecanvas');
img.src = 'http://www.photographyblogger.net/wp-content/uploads/2009/12/Picture-in-a-picture4.jpg';
img.onload = function() {
    var ctx = cv.getContext('2d');
    cv.style.width = img.width + 'px';
    cv.style.height = img.height + 'px';
    ctx.drawImage(img, 0, 0);
};

For example, I'm trying to draw this (sorry about the big images :/)

Expected Image

But end up with this

Actual image

What could be causing this?

KJ Tsanaktsidis
  • 1,255
  • 1
  • 17
  • 28

1 Answers1

10

You need to assign the canvas actual width and height, not via its style:

cv.width = img.width;
cv.height = img.height;

Live test case.

As for the why, well, it's explained already here.

Community
  • 1
  • 1
Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
  • Man that was quick! Absolutely right, in my real code I was using jQuery $().width() and height(), which set the style. And you get bonus points because the page you linked to explains how i can decouple the size of the canvas backing store from what's actually displayed, saving me from writing lots of ugly transformation code to handle resizing. Thanks a bunch! – KJ Tsanaktsidis Oct 13 '13 at 12:33
  • Cheers @KJTsanaktsidis - lucky for you, I happened to stumble on this very problem not long ago so it's still fresh. (and yes, jQuery too! :)) – Shadow The GPT Wizard Oct 13 '13 at 12:34
  • Update: The `width()` and `height()` functions [work a little differently in jQuery 3.0](https://jquery.com/upgrade-guide/3.0/#breaking-change-width-height-css-quot-width-quot-and-css-quot-height-quot-can-return-non-integer-values). – jkdev Jul 06 '16 at 02:49
  • @jkdev you mean they fixed it? In this case better ping the OP of the question, either here since he posted a comment too, or in a comment on the question itself. – Shadow The GPT Wizard Jul 06 '16 at 06:24
  • @ShadowWizard It depends on what you mean by "fixed." Previously, `width()` and `height()` in jQuery used `offsetWidth` and `offsetHeight` which always return integers. [In jQuery 3.0.0, this is changed](https://jquery.com/upgrade-guide/3.0/#breaking-change-width-height-css-quot-width-quot-and-css-quot-height-quot-can-return-non-integer-values) to measure an element's width and height using `getBoundingClientRect`. [There's some debate about whether this was a good idea.](https://github.com/jquery/jquery/issues/3193) In any event, I see your point -- I'll ping the OP as well. @KJTsanaktsidis – jkdev Jul 06 '16 at 06:41