13

I'm trying to resize a <canvas> with an image already drawn, but I'm misunderstanding how to use the canvas.scale() method because it doesn't shrink...

Code:

ImageRender.prototype.resizeTo = function () {

    var canvas          = $('#myCanvas')[0];
    var ctx             = canvas.getContext("2d");

    //current image
    var currImg         = ctx.getImageData(0, 0, canvas.width, canvas.height);

    //
    var tempCanvas      = $('canvas')[0];
    var tempCtx         = tempCanvas.getContext("2d");
    tempCtx.putImageData(currImg, 0, 0)

    //
    ctx.scale(0.5, 0.5);

    //redraw
    ctx.drawImage(tempCanvas, 0, 0);
  };

What am I overlooking?

Thanks!

3
  • Please post a code snippet that can reproduce this issue. Also, see ctx.scale() docs. Commented Jan 18, 2016 at 23:57
  • please replace ctx.scale(0.5, 0.5) with canvas.scale(0.5, 0.5); Commented Jan 19, 2016 at 0:16
  • You can use getImageData/putImageData to crop, but context.scale only affects subsequent drawings, so putImageData won't scale for you because (1) it was created before scaling, and (2) its not actually a drawing -- it's simply replacing pixel-by-pixel back on the canvas. ;-) Commented Jan 19, 2016 at 1:22

2 Answers 2

15

You can scale your canvas with content by "bouncing" the content off a temporary canvas while you resize the original canvas. This save+redraw process is necessary because canvas content is automatically cleared when you resize the canvas width or height.

Example code:

enter image description here

var myCanvas=document.getElementById("canvas");
var ctx=myCanvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var tempCanvas=document.createElement("canvas");
var tctx=tempCanvas.getContext("2d");

var img=new Image();
img.crossOrigin='anonymous';
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/Dog-With-Cute-Cat.jpg";
function start(){
  myCanvas.width=img.width;
  myCanvas.height=img.height;
  ctx.drawImage(img,0,0);
  resizeTo(myCanvas,0.50);
}

function resizeTo(canvas,pct){
  var cw=canvas.width;
  var ch=canvas.height;
  tempCanvas.width=cw;
  tempCanvas.height=ch;
  tctx.drawImage(canvas,0,0);
  canvas.width*=pct;
  canvas.height*=pct;
  var ctx=canvas.getContext('2d');
  ctx.drawImage(tempCanvas,0,0,cw,ch,0,0,cw*pct,ch*pct);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<h4>Canvas resized to 50%</h4>
<canvas id="canvas" width=300 height=300></canvas>
<h4>Img with original image</h4>
<img src='https://dl.dropboxusercontent.com/u/139992952/multple/Dog-With-Cute-Cat.jpg'>

Sign up to request clarification or add additional context in comments.

6 Comments

So .scale() doesn't work? What's that function for then...?
Worked great for me scaling images and pdf views. +1
@Hasen .scale() just applies a transform draw operations. ie. doing ctx.scale(3, 0.5) and then drawing with ctx.rect(0, 0, 100, 100) will actually draw a rect that is 300, 50 in size. The scale method is a simplified version of setTransform() in this regard, check out the docs for a better explanation.
@Magikarp Based on your description that would seem to be 'scaling' rather than transforming, but it clearly didn't work like that for the op.
@Hasen The way you described it indicated to me that you haven't read the documentation for the scale or setTransform methods, which include examples showing how they're used. scale only sets height/width transform while setTransform uses a 3x3 matrix is capable of effects like shear/perspective. They both function similarly in what they actually do and are identical in how they're used (they affect size of content that is drawn after calling). MDN could improve on this by adding a note about drawImage's exception to this, but otherwise this is also a misunderstanding of their usage.
|
7

Simpler way would be using the extra parameters of drawImage(). 4th and 5th parameters let you set the final width and height.

Also, you can paint an image (or a canvas) directly, without the need of getting the ImageData.

Also(2), I think you may want to resize the canvas too (just use its width and height properties)

https://jsfiddle.net/mezeL06o/

2 Comments

This is good, but based on his previous question, I think the questioner instead wants to resize the existing canvas content rather than scaling the img.
I did that too in the jsfiddle

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.