JavaScript - 旋转 canvas 图像,边角被剪掉

JavaScript - Rotate canvas image, corners are clipped off

我正在尝试在 HTML canvas 中旋转图像。旋转确实有效,但是,每次旋转一次,图像的角都会 cut/clipped 关闭。这是错误的,因为整个上传的图像在旋转后应该是完整的。

一些重要细节:

所以这里的问题是,每次我想将图像旋转 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

如有任何疑问,请告诉我!