gpt4 book ai didi

javascript - 如何将图像放在我使用路径绘制的梯形 html Canvas 上

转载 作者:行者123 更新时间:2023-12-03 04:39:23 29 4
gpt4 key购买 nike

[我想在笔记本电脑屏幕上添加另一个图像`var ctx = myCanvas.getContext('2d');

                ctx.beginPath();
ctx.moveTo(13,28);
ctx.lineTo(237,7);
ctx.lineTo(285,105);
ctx.lineTo(73,151);
ctx.closePath();
ctx.lineWidth = 0.5;
ctx.strokeStyle = 'blue';
ctx.stroke();
//ctx.clip();
//ctx.rotate(-20*Math.PI/180);
var img = new Image;
img.onload = function()
{

var width = img.width;
var height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height,
0, 0, myCanvas.width, myCanvas.height);

}
};
img.src = reader.result;
`][1]

如何倾斜图像以适合我创建的梯形 ctx

最佳答案

为什么 2D API 是 2D

canvas 2D API 被称为 2D API 是有充分理由的。它只能进行 2D 转换。

非二维

你的形状...

enter image description here

上图注释了您的形状。线 A、C 不平行。

2D 最佳拟合

Canvas 2D 变换无法使矩形适合该形状,因为它没有携带足够的信息来处理会聚线以及如何在像素会聚时缩放像素。

你能做的最好的就是近似

下一张图片使用两条线将形状一分为二。这些线将用于使用 2D 变换创建最适合形状的变换。

enter image description here

我们使用平分线来定义变换的 x 轴和 y 轴,并使用每个轴的长度来确定比例。图像的中心点是其中一条等分线的中心。

enter image description here

const ctx = canvas.getContext("2d");
const path = [13, 28, 237, 7, 285, 105, 73, 151];
const imageURL = "https://upload.wikimedia.org/wikipedia/commons/thumb/5/55/Sarcoramphus_papa_%28K%C3%B6nigsgeier_-_King_Vulture%29_-_Weltvogelpark_Walsrode_2013-01.jpg/675px-Sarcoramphus_papa_%28K%C3%B6nigsgeier_-_King_Vulture%29_-_Weltvogelpark_Walsrode_2013-01.jpg";
function setStyle(style){
Object.keys(style).forEach(key => ctx[key] = style[key]);
}
function drawPath(path, style) {
var i = 0;
setStyle(style);
ctx.beginPath();
ctx.moveTo(path[i++], path[i++]);
while (i < path.length) {
ctx.lineTo(path[i++], path[i++]);
}
ctx.closePath();
ctx.stroke();
}
function markPath(path, style, marks) {
var i = 0;
var len = path.length;
setStyle(style);
while (i < len) {
ctx.fillText(
marks[i >> 1],
(path[i] + path[((i++) + 2) % len]) / 2,
(path[i] + path[((i++) + 2) % len]) / 2
);
}
}
function bisectPath(path, modulo, style) {
var i = 0;
var len = path.length;
setStyle(style);
ctx.beginPath();
while (i < len) {
ctx.moveTo(
(path[i] + path[((i++) + 2) % len]) / 2,
(path[i] + path[((i++) + 2) % len]) / 2
);
i += modulo;
ctx.lineTo(
(path[i] + path[((i++) + 2) % len]) / 2,
(path[i] + path[((i++) + 2) % len]) / 2
);
i -= modulo + 2;
}
ctx.stroke();

}

// functions to create lines, get vectors, length and normals
function getLine(x1,y1,x2,y2){
return {
p1 : { x : x1 , y : y1 },
p2 : { x : x2 , y : y2 }
};
}
function getVec(line){
line.vec = {
x : line.p2.x - line.p1.x,
y : line.p2.y - line.p1.y
};
return line;
}
function getNormal(line){
line.len = Math.hypot(line.vec.x, line.vec.y);
line.norm = {
x : line.vec.x / line.len,
y : line.vec.y / line.len,
};
return line;
}
// create the 2 bisecting lines
var line1 = getNormal( getVec( getLine(
(path[0] + path[2]) / 2,
(path[1] + path[3]) / 2,
(path[4] + path[6]) / 2,
(path[5] + path[7]) / 2
)));
var line2 = getNormal( getVec( getLine(
(path[6] + path[0]) / 2,
(path[7] + path[1]) / 2,
(path[2] + path[4]) / 2,
(path[3] + path[5]) / 2
)));

// create an image to fit
var image = new Image;
image.src = imageURL;
image.onload = function(){
var w, h, sx, sy, cx, cy;
w = this.width;
h = this.height;
// calculate the image scales
sx = line2.len / w;
sy = line1.len / h;
// calculate the center
cx = (line1.p1.x + line1.p2.x) / 2;
cy = (line1.p1.y + line1.p2.y) / 2;

// now we have all the information needed to create the transformation
ctx.setTransform(
line2.norm.x * sx, // scale and direction of x axis
line2.norm.y * sx,
line1.norm.x * sy, // scale and direction of y axis
line1.norm.y * sy,
cx, cy, // the origin coordinate (0,0)
);
// Draw the image offset from its center by half its width and heigth
ctx.drawImage(this, -w / 2, -h / 2);
// reset the transformation
ctx.setTransform(1,0,0,1,0,0);

// draw the guides
drawPath(path, {
lineWidth : 0.5,
strokeStyle : "blue"
});
bisectPath(path, 2, {
lineWidth : 1,
strokeStyle : "white"
});
markPath(path, {
font : "18px arial",
textAlign : "center",
textBaseline : "middle",
fillStyle : "black"
}, ["A", "B", "C", "D"]);





}
<canvas id=canvas height=160></canvas>

这是使用 canvas 2D API 所能做的最好的事情。您可以渲染每个像素,计算 3D 变换以适合您拥有的形状。根据图像大小,可能需要一些时间(CPU)来完成,结果就可以了。

3D WebGL

如果您确实需要 3D 变换,您应该使用 webGL。 SO 和网络上有很多关于如何做到这一点的示例

关于javascript - 如何将图像放在我使用路径绘制的梯形 html Canvas 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43147714/

29 4 0