gpt4 book ai didi

javascript - setTransform 和 Scale 以使 Canvas 适合给定图像

转载 作者:行者123 更新时间:2023-12-01 00:38:36 26 4
gpt4 key购买 nike

我在 Canvas 上有一张图像。渲染图像后,我将 Canvas 顺时针旋转 90 度,然后必须缩放以适合 Canvas 。

Scaling an image to fit on canvas Resize image and rotate canvas 90 degrees

有很多可用的解决方案,但不幸的是它们都不适合我

这就是我现在所拥有的。

width = 300; // after rotation
height = 400; // after rotation
var scale = width / img.height; // how much to scale the image to fit

console.log(scale);
canvas.width = width;
canvas.height = height;
ctx.setTransform(
0, scale, // x axis down the screen
-scale, 0, // y axis across the screen from right to left
width, // x origin is on the right side of the canvas
0 // y origin is at the top
);
ctx.drawImage(img, 0, 0);
ctx.setTransform(1, 0, 0, 1, 0, 0); // restore default

目前, Canvas 旋转良好,但图像无法根据 Canvas 宽度和高度正确调整或缩放。原始图像很大,我想将其缩放到 Canvas 上 300x400。

原始图像 - enter image description here

实际结果图像如下所示,未缩放完整图像 -

enter image description here

最佳答案

要使图像适合显示区域,请使用最小比例来适合高度或适合宽度。

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

// image is assumed loaded and ready to be drawn

// Get min scale to fit
var 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

更新

重新评论

由于您遇到了麻烦,而且我仍然不确定图像要做什么,这里有一个通用函数,可以以 90 度为步长旋转图像,并进行缩放以适合、填充和自然。 (底部片段中的演示版本稍微不那么冗长)

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

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

// modified transform image width and height to match the xAxis
const 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);
} else if (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);
}

并确保以下是使用您的图像进行测试的运行示例。

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

function drawRotatedImage(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 = new Image;
const tests = [[0,"fit"], [1,"fit"], [2,"fit"], [3,"fit"],[0,"fill"], [1,"fill"], [2,"fill"], [3,"fill"]];

tests.clicker = 0;
img.src = "/image/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;
}
<canvas id="canvas"></canvas>

<div id="info"></div>

关于javascript - setTransform 和 Scale 以使 Canvas 适合给定图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57896390/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com