1

I have a fairly simple test, a 400 x 400 white image with text on it saying "1" over and over again.

I draw it on a fairly simple 1000 x 1000 canvas, trying to resize it to 100 x 100.

var image = new Image();
document.body.appendChild(image);

image.addEventListener("load",function (event) {
    var image1 = event.target;
    var tempCanvas = window.document.createElement("canvas");

    tempCanvas.style.width = "1000px";
    tempCanvas.style.height = "1000px";
    tempCanvas.style.background = "rgba(0, 0, 0, 0.1)";

    document.body.appendChild(tempCanvas);

    tempCanvas.getContext("2d").drawImage(image1, 0, 0, 100, 100);
});

image.src = "1.png";

But despite all that being squares, I end up with an odd-looking, deformed, weirdly scaled result that's rectangular, low quality, and without having any of its dimensions being 100px.

Odd result

On the left, you can see the original image, on the right, that's the top left corner of my canvas.

If you want the original image, here it is: https://i.stack.imgur.com/yDkLx.png

What am I missing?

Lily Bergonzat
  • 396
  • 5
  • 21

1 Answers1

1

Try setting the width and height values on the canvas element prior to the drawImage(), rather than relying on the styles as you are.

Setting the width and height attributes corresponds to setting the dimensions of that canvas element.

Once you've defined the dimensions of a canvas element, the rendering behavior of the canvas becomes much more predicatable:

var image = new Image();
document.body.appendChild(image);

image.addEventListener("load",function (event) {
    var image1 = event.target;
    var tempCanvas = window.document.createElement("canvas");

    //tempCanvas.style.width = "400px";
    //tempCanvas.style.height = "400px";
    tempCanvas.style.background = "rgba(0, 0, 0, 0.1)";

    tempCanvas.width = 100;
    tempCanvas.height = 100;

    document.body.appendChild(tempCanvas);

    tempCanvas.getContext("2d").drawImage(image1, 0, 0, 100, 100);
});

image.src = "https://puu.sh/C4HE2/d96b531d08.png";
canvas {
  border:1px solid blue;
}

img {
  border:1px solid red;
}

The code snippet above shows the original source image with red border, and the down-scaled canvas rendered image with blue border - hope this helps!

Dacre Denny
  • 29,664
  • 5
  • 45
  • 65
  • If I do that, the image is still weirdly resized, only thing is the canvas is smaller. Also, that doesn't suit my needs, I won't always have an image that's exactly the size of the canvas. https://puu.sh/C4Hz2/b81c6f836d.png – Lily Bergonzat Nov 20 '18 at 04:26
  • strange - can you please upload your source image, eg the image with the 1's – Dacre Denny Nov 20 '18 at 04:27
  • https://i.stack.imgur.com/yDkLx.png Done :) – Lily Bergonzat Nov 20 '18 at 04:28
  • 1
    @YannBergonzat thanks :-) , just updated answer with code snippet - seems to work for me, does this produce expected results for you? – Dacre Denny Nov 20 '18 at 04:32
  • Okay so the answer, which I found thanks to your updated snippet, is that I shouldn't set the width and the height of my canvas through the style attribute, but through the width and height attributes directly or else it just screws every operation because I guess they rely on these values and not on the CSS ones. Could you clear that up in your answer please so I can check it? – Lily Bergonzat Nov 20 '18 at 04:34
  • 1
    @YannBergonzat yes that's correct - typically when you work with canvas, you'll want to set the width and height to define the resolution/dimensions of the canvas. The styling just sets the dimensions of the canvas in terms of the box-model, which bear no meaning when calling functions like drawImage() – Dacre Denny Nov 20 '18 at 04:37