Skip to content Skip to sidebar Skip to footer

Settransform And Scale To Fit Canvas For The Given Image

I have an image on Canvas. After rendering an image, I rotate the canvas to 90 degrees clockwise and then have to scale to fit the canvas. Scaling an image to fit on canvas Resiz

Solution 1:

To fit an image to a display area, use the min scale to fit height or fit width.

// size of canvasconst width = 100; 
const height = 298;

// image is assumed loaded and ready to be drawn// Get min scale to fitvar scale = Math.min(width / image.width , height / image.height);

// you can also scale to fill using max// var scale = Math.max(width / image.width , height / image.height);

canvas.width = width;
canvas.height = height;

// // draw image from top left corner
ctx.setTransform(scale, 0, 0, scale, 0, 0);
ctx.drawImage(image, 0, 0);
ctx.setTransform(1, 0, 0, 1, 0, 0); // restore default

Update

Re comment

As you are having trouble, and I am still not sure what you what the image to do, here is a general purpose function to rotate image in 90 deg steps, and scales to fit, fill, and natural. (Demo version in bottom snippet a little less verbose)

// img image to draw// rot 1 unit = 90 deg. scaleType fit or fillfunctiondrawRotatedImage(img, rot = 1, scaleType = "fit") {
  const w = img.naturalWidth;
  const h = img.naturalHeight;

  // direction of xAxisvar xAxisX = Math.cos(rot * Math.PI / 2);
  var xAxisY = Math.sin(rot * Math.PI / 2);

  // modified transform image width and height to match the xAxisconst tw = Math.abs(w * xAxisX - h * xAxisY);
  const th = Math.abs(w * xAxisY + h * xAxisX);

  var scale = 1; 
  if (scaleType === "fit") {
    scale = Math.min(canvas.width / tw, canvas.height / th);
  } elseif (scaleType === "fill") {
    scale = Math.max(canvas.width / tw, canvas.height / th);
  }

  xAxisX *= scale;
  xAxisY *= scale;

  // Rotate scale to match scaleType . Center on canvas
  ctx.setTransform(xAxisX, xAxisY, -xAxisY, xAxisX, canvas.width / 2, canvas.height / 2);

  // Image drawn offset so center is at canvas center
  ctx.drawImage(img, -w / 2, -h / 2, w, h);
}

And to make sure the following is a tested runing example using your image.

const canWidth = 300;
const canHeight = 400;
const rot = 1;           
const scaleType = "fit"; 
constPI90 = Math.PI / 2;

functiondrawRotatedImage(img, rot, scale) {
  ctx.setTransform(1, 0, 0, 1, 0, 0); 
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  const w = img.naturalWidth, h = img.naturalHeight;
  var xAX = Math.cos(rot *= PI90 ), xAY = Math.sin(rot);
  const tw = Math.abs(w * xAX - h * xAY);
  const th = Math.abs(w * xAY + h * xAX);
  scale = Math[scale === "fit" ? "min" : "max" ](canvas.width / tw, canvas.height / th);
  xAX *= scale;
  xAY *= scale;
  ctx.setTransform(xAX, xAY, -xAY, xAX, canvas.width / 2, canvas.height / 2);
  ctx.drawImage(img, -w / 2, -h / 2, w, h);
}









// Stuff for demo and test. unrelated to answer.const ctx = canvas.getContext("2d");  
// size canvas
canvas.width = canWidth;
canvas.height = canHeight;
const img = newImage;
const tests = [[0,"fit"], [1,"fit"], [2,"fit"], [3,"fit"],[0,"fill"], [1,"fill"], [2,"fill"], [3,"fill"]];

tests.clicker = 0;
img.src = "https://i.stack.imgur.com/SQmuv.jpg";
img.addEventListener("load", () => {
  info.textContent = ((rot % 4) * 90) + "deg CW scaled to " + scaleType.toUpperCase() + " click canvas to rotate and switch scales";
  drawRotatedImage(img, rot, scaleType)
});


canvas.addEventListener("click",() => {
  const test = tests[tests.clicker++ % tests.length];
  info.textContent = ((test[0] % 4) * 90) + "deg CW scaled to " + test[1].toUpperCase();
  drawRotatedImage(img, ...test)
});
body {
   font-family: "arial black";
}
canvas {
  border: 1px solid black;
  position: absolute;
  top: 30px;
  left: 10px;    
}
#info {
  position: absolute;
  top: 2px;
  left: 10px;
}
<canvasid="canvas"></canvas><divid="info"></div>

Post a Comment for "Settransform And Scale To Fit Canvas For The Given Image"