我正在尝试使用具有JavaScript的HTML5中的canvas对象的draw image功能来切出图像的最大可能正方形区域。另外,剪切区域应位于原始图像的中心。
(我还在图像上方绘制水印。)
这很好,无需尝试剪切图像的中心,但是每当我尝试这样做时,结果都会扭曲。
下面的代码段中也提供了变形图像的示例!
要裁剪图像的一部分,您必须声明两个坐标P1和P2 ,每两个变量。
坐标系为like this(我认为):
我正在使用以下方法计算P1和P2:
imagewidth
P1:
----
x1 = 0
y1 = (imageheight / 2) - (imagewidth / 2)
// if I'm replacing y1 with 0, it wont get warped
// but it will cut out the top of the image
and
P2:
----
x2 = imagewidth
y2 = y1 + imagewidth
imagewidth> imageheight
P1:
----
x1 = (imagewidth / 2) - (imageheight / 2)
y1 = 0
// if I'm replacing x1 with 0, it wont get warped
// but it will cut out the most left part of the image
and
P2:
----
x2 = x1 + imageheight
y2 = imageheight
基本上它将写入该对象:
<div id="buy_imagelist" class=imagelist></div>
javascript:
var numbers = ["images/test_images/bluefireoly-2.jpg"];
var txt = "";
var numCanvas = 0;
for(var src in numbers) {
numCanvas++;
}
var i = 0;
for(var src in numbers) {
txt = txt + '<canvas class=imagelistsingle style=padding:7px id=myCanvas' + i + ' width="300" height="300"></canvas>';
i++;
}
document.getElementById('buy_imagelist').innerHTML = txt;
var imageNumber_canvas = 0;
numbers.forEach(myFunction);
function myFunction(value, index, array) {
var canvas = document.getElementById('myCanvas' + imageNumber_canvas);
if(canvas == null) {
window.alert("Error - Images could not be loaded");
}
var context = canvas.getContext('2d');
function loadImages(imagelist, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
for(var src in imagelist) {
numImages++;
}
for(var src in imagelist) {
images[src] = new Image();
images[src].onload = function() {
if(++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = imagelist[src];
}
}
var imagelist = {
testimage: value,
wasserzeichen: "images/wasserzeichen/wasserzeichen_1.png"
};
loadImages(imagelist, function(images) {
var testimage = images.testimage;
var imagewidth = testimage.naturalWidth;
var imageheight = testimage.naturalHeight;
var x1 = 0;
var y1 = 0;
var x2 = imagewidth;
var y2 = imageheight;
if(imagewidth !== imageheight) {
if(imageheight < imagewidth) {
x1 = (imagewidth / 2) - (imageheight / 2);
y1 = 0;
x2 = x1 + imageheight;
y2 = imageheight;
} else {
x1 = 0;
y1 = (imageheight / 2) - (imagewidth / 2);
x2 = imagewidth;
y2 = y1 + imagewidth;
}
}
context.drawImage(testimage, x1, y1, x2, y2, 0, 0, 300, 300);
context.drawImage(images.wasserzeichen, 0, 0, 300, 300);
});
imageNumber_canvas++;
}
如预期的那样,这对方形图像效果很好。
错误必须在此处某处(尤其是在我用“ //!”标记的地方)
var testimage = images.testimage;
var imagewidth = testimage.naturalWidth;
var imageheight = testimage.naturalHeight;
var x1 = 0;
var y1 = 0;
var x2 = imagewidth;
var y2 = imageheight;
if(imagewidth !== imageheight) {
if(imageheight < imagewidth) {
x1 = (imagewidth / 2) - (imageheight / 2); //!
y1 = 0;
x2 = x1 + imageheight;
y2 = imageheight;
} else {
x1 = 0;
y1 = (imageheight / 2) - (imagewidth / 2); //!
x2 = imagewidth;
y2 = y1 + imagewidth;
}
}
context.drawImage(testimage, x1, y1, x2, y2, 0, 0, 300, 300);
context.drawImage(images.wasserzeichen, 0, 0, 300, 300);
对于上面给出的非正方形图像(1028x1920)(宽度<高度)
-> y1 = 446
->所以y2 = 446 + 1028 = 1474
所以y1> 0
所以y2 <高度
-> 剪切正方形应适合原始图像
使用此代码亲自尝试一下: (点击“整页”以查看图像)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example</title>
</head>
<body>
<div id="buy_imagelist" class=imagelist></div>
<script>
var numbers = ["https://i.pinimg.com/originals/46/1c/01/461c0133da95e315cd4e245f79219ec0.jpg"];
var txt = "";
var numCanvas = 0;
for (var src in numbers) {
numCanvas++;
}
var i = 0;
for (var src in numbers) {
txt = txt + '<canvas class=imagelistsingle style=padding:7px id=myCanvas' + i + ' width="300" height="300"></canvas>';
i++;
}
document.getElementById('buy_imagelist').innerHTML = txt;
var imageNumber_canvas = 0;
numbers.forEach(myFunction);
function myFunction(value, index, array) {
var canvas = document.getElementById('myCanvas' + imageNumber_canvas);
if (canvas == null) {
window.alert("Error - Images could not be loaded");
}
var context = canvas.getContext('2d');
function loadImages(imagelist, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
for (var src in imagelist) {
numImages++;
}
for (var src in imagelist) {
images[src] = new Image();
images[src].onload = function() {
if (++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = imagelist[src];
}
}
var imagelist = {
testimage: value
};
loadImages(imagelist, function(images) {
var testimage = images.testimage;
var imagewidth = testimage.naturalWidth;
var imageheight = testimage.naturalHeight;
var x1 = 0;
var y1 = 0;
var x2 = imagewidth;
var y2 = imageheight;
if (imagewidth !== imageheight) {
if (imageheight < imagewidth) {
x1 = (imagewidth / 2) - (imageheight / 2);
y1 = 0;
x2 = x1 + imageheight;
y2 = imageheight;
} else {
x1 = 0;
y1 = (imageheight / 2) - (imagewidth / 2);
x2 = imagewidth;
y2 = y1 + imagewidth;
}
}
context.drawImage(testimage, x1, y1, x2, y2, 0, 0, 300, 300);
});
imageNumber_canvas++;
}
</script>
</body>
</html>
答案 0 :(得分:1)
drawImage
方法的第4个和第5个参数是width
和height
,而不是x2
和y2
。
MDN上的文档在第一个示例中使用了此
ctx.drawImage(image, 33, 71, 104, 124, 21, 20, 87, 104);
附带说明
源图像是从坐标(33,71)拍摄的,宽度为104,高度为124。在(21,20)处将其绘制到画布上,在该画布上给定的宽度为87,身高104。
tl; dr
您必须提供剪切图像的宽度/高度,而不是右下角的坐标:
context.drawImage(testimage, x1, y1, x2 - x1, y2 - y1, 0, 0, 300, 300);