JavaScript - 旋转 canvas 图像,边角被剪掉
JavaScript - Rotate canvas image, corners are clipped off
我正在尝试在 HTML canvas
中旋转图像。旋转确实有效,但是,每次旋转一次,图像的角都会 cut/clipped 关闭。这是错误的,因为整个上传的图像在旋转后应该是完整的。
一些重要细节:
- 在我的特定用例中,我无法访问图像数据本身。所以用户上传的图片会在HTMLcanvas上进行处理绘制。我只能访问 HTML canvas 元素,不能访问上传的图像本身。这就是系统的工作原理。
- canvas宽度和高度应与上传图片的宽度和高度完全相同
- canvas 本身应保持其尺寸且不应旋转,只有其中的图像应旋转。
- 否 CSS,只应使用 JavaScript 存档,因为旋转后的 canvas 图片将上传到服务器。
所以这里的问题是,每次我想将图像旋转 45 度时,HTML canvas 中图像的角都会 clipped/cutted 关闭。显然这是不正确的,因为应该旋转整个图像。我不知道我做错了什么,所以也许有人可以进一步帮助我?
https://jsfiddle.net/d5zurxq2/
<label>Image File:</label><br/>
<input type="file" id="imageLoader" name="imageLoader"/>
<canvas id="imageCanvas" width=250 height=250></canvas>
<br /><br /><br />
<button type="button" id="rotateLeft">Rotate 45 degrees left</button>
#imageCanvas {
width: 350px;
height: 250px;
background-color: rgba(158, 167, 184, 0.2)
}
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext("2d");
function handleImage(e){
var reader = new FileReader();
reader.onload = function(e) {
var preview = document.createElement('img');
preview.onload = function()
{
canvas.width = preview.width;
canvas.height = preview.height;
canvas.getContext('2d').drawImage(preview, 0, 0);
};
preview.src = reader.result;
};
reader.readAsDataURL(e.target.files[0]);
}
document.getElementById('rotateLeft').addEventListener('click', rotateImage,
false);
function rotateImage() {
var w = ctx.canvas.width;
var h = ctx.canvas.height;
var ww = w / 2;
var hh = h / 2;
ctx.save();
ctx.globalCompositeOperation = "copy";
ctx.translate(ww, hh);
ctx.rotate((Math.PI / 180) * 45);
ctx.drawImage(canvas, -canvas.width/2, -canvas.height/2);
ctx.restore();
}
这两种说法是矛盾的
The canvas width and height should be exact the same as the width &
height of the uploaded image.
The canvas itself should maintain its
dimensions and should not be rotated, only the image in it should be
rotated.
增加 canvas 的尺寸。如果将图像旋转 45 度,则需要更大的 canvas。
现在,您将 canvas 大小设置为图像大小。但是,旋转图像不会旋转 canvas,这是边缘被切断的原因。
这是一个 canvas(蓝色),图像(黄色)大小完全相同,但以 45 度角绘制。突出的图像边缘未绘制...因为它们不在 canvas.
上
增加canvas尺寸以补偿图像旋转。我建议计算图像的对角线长度并将其设置为 canvas 的宽度和高度,这样无论您如何旋转它,它都会适合。
像这样:
let diagonalLength = Math.sqrt(
Math.pow(preview.width,2)+Math.pow(preview.height,2)
);
canvas.width = diagonalLength;
canvas.height = diagonalLength;
您可以使用 Canvate 库做到这一点以及更多。
http://www.sakuracode.com/canvate
您可以根据需要加载所有图像并将它们视为单独的剪辑。
您也可以设置旋转点。在这种情况下在中间。
你需要这样的东西吗?
function rotateImage() {
clip.rotation = 45;
clip.fitInto(canvas.width, canvas.height);
}
https://codepen.io/EiseiKashi/pen/aGjbWK
如有任何疑问,请告诉我!
我正在尝试在 HTML canvas
中旋转图像。旋转确实有效,但是,每次旋转一次,图像的角都会 cut/clipped 关闭。这是错误的,因为整个上传的图像在旋转后应该是完整的。
一些重要细节:
- 在我的特定用例中,我无法访问图像数据本身。所以用户上传的图片会在HTMLcanvas上进行处理绘制。我只能访问 HTML canvas 元素,不能访问上传的图像本身。这就是系统的工作原理。
- canvas宽度和高度应与上传图片的宽度和高度完全相同
- canvas 本身应保持其尺寸且不应旋转,只有其中的图像应旋转。
- 否 CSS,只应使用 JavaScript 存档,因为旋转后的 canvas 图片将上传到服务器。
所以这里的问题是,每次我想将图像旋转 45 度时,HTML canvas 中图像的角都会 clipped/cutted 关闭。显然这是不正确的,因为应该旋转整个图像。我不知道我做错了什么,所以也许有人可以进一步帮助我?
https://jsfiddle.net/d5zurxq2/
<label>Image File:</label><br/>
<input type="file" id="imageLoader" name="imageLoader"/>
<canvas id="imageCanvas" width=250 height=250></canvas>
<br /><br /><br />
<button type="button" id="rotateLeft">Rotate 45 degrees left</button>
#imageCanvas {
width: 350px;
height: 250px;
background-color: rgba(158, 167, 184, 0.2)
}
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext("2d");
function handleImage(e){
var reader = new FileReader();
reader.onload = function(e) {
var preview = document.createElement('img');
preview.onload = function()
{
canvas.width = preview.width;
canvas.height = preview.height;
canvas.getContext('2d').drawImage(preview, 0, 0);
};
preview.src = reader.result;
};
reader.readAsDataURL(e.target.files[0]);
}
document.getElementById('rotateLeft').addEventListener('click', rotateImage,
false);
function rotateImage() {
var w = ctx.canvas.width;
var h = ctx.canvas.height;
var ww = w / 2;
var hh = h / 2;
ctx.save();
ctx.globalCompositeOperation = "copy";
ctx.translate(ww, hh);
ctx.rotate((Math.PI / 180) * 45);
ctx.drawImage(canvas, -canvas.width/2, -canvas.height/2);
ctx.restore();
}
这两种说法是矛盾的
The canvas width and height should be exact the same as the width & height of the uploaded image.
The canvas itself should maintain its dimensions and should not be rotated, only the image in it should be rotated.
增加 canvas 的尺寸。如果将图像旋转 45 度,则需要更大的 canvas。
现在,您将 canvas 大小设置为图像大小。但是,旋转图像不会旋转 canvas,这是边缘被切断的原因。
这是一个 canvas(蓝色),图像(黄色)大小完全相同,但以 45 度角绘制。突出的图像边缘未绘制...因为它们不在 canvas.
上增加canvas尺寸以补偿图像旋转。我建议计算图像的对角线长度并将其设置为 canvas 的宽度和高度,这样无论您如何旋转它,它都会适合。
像这样:
let diagonalLength = Math.sqrt(
Math.pow(preview.width,2)+Math.pow(preview.height,2)
);
canvas.width = diagonalLength;
canvas.height = diagonalLength;
您可以使用 Canvate 库做到这一点以及更多。
http://www.sakuracode.com/canvate
您可以根据需要加载所有图像并将它们视为单独的剪辑。 您也可以设置旋转点。在这种情况下在中间。
你需要这样的东西吗?
function rotateImage() {
clip.rotation = 45;
clip.fitInto(canvas.width, canvas.height);
}
https://codepen.io/EiseiKashi/pen/aGjbWK
如有任何疑问,请告诉我!