【问题标题】:JavaScript - Rotate canvas image, corners are clipped offJavaScript - 旋转画布图像,角落被剪掉
【发布时间】:2018-10-23 05:30:42
【问题描述】:

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

一些重要的细节:

  • 在我的特定用例中,我无法访问图像数据本身。因此,用户上传的图像将在 HTML 画布上进行处理和绘制。我只能访问 HTML 画布元素,而不是上传的图像本身。这就是系统的工作原理。
  • 画布宽度和高度应与上传图片的宽度和高度完全相同
  • 画布本身应保持其尺寸且不应旋转,仅应旋转其中的图像。
  • 无 CSS,只能使用 JavaScript 归档,因为旋转后的画布图像将上传到服务器。

所以这里的问题是,每次我想将图像旋转 45 度时,HTML 画布内的图像角都会被剪掉/剪掉。显然这是不正确的,因为应该旋转整个图像。我不知道我做错了什么,所以也许有人可以帮助我进一步?

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();
}

【问题讨论】:

    标签: javascript canvas rotation


    【解决方案1】:

    这两种说法是矛盾的。

    画布的宽度和高度应与宽度和高度完全相同 上传图片的高度。

    画布本身应保持其 尺寸,不应旋转,只有其中的图像应该是 旋转。

    增加画布的大小。如果将图像旋转 45 度,则需要更大的画布。

    现在,您将画布大小设置为图像大小。但是,旋转图像不会旋转画布,这就是边缘被切断的原因。

    这是一个画布(蓝色),图片(黄色)大小完全相同,但以 45 度角绘制。突出的图像边缘未绘制...因为它们不在画布上。

    增加画布大小以弥补图像旋转。我建议计算图像的对角线长度并将其设置为画布的宽度和高度,这样无论您如何旋转它,它都会适合。

    类似这样的:

      let diagonalLength = Math.sqrt(
        Math.pow(preview.width,2)+Math.pow(preview.height,2)    
      );
      canvas.width  = diagonalLength;
      canvas.height = diagonalLength;
    

    【讨论】:

    • 这很好解释。我确实理解并且通过您的代码示例,我能够获得一个未剪裁的画布,这很好,所以谢谢您!但是,画布的宽度和高度与原始上传的图像不同。我的意思是,当用户上传 250x500 像素的图像时,画布在所有情况下都必须在旋转 250x500 之后。这可以以某种方式归档吗,例如缩放图像以适合画布大小?
    • 是的@Hendrian,您只需要弄清楚您想以哪个比例绘制它。 stackoverflow.com/questions/13903257/…
    • 谢谢,我会玩的。此问题已标记为已解决。
    【解决方案2】:

    使用 Canvate 库,您可以做到这一点,甚至更多。

    http://www.sakuracode.com/canvate

    您可以根据需要加载所有图像并将它们视为单独的剪辑。 您也可以设置旋转点。在这种情况下在中间。

    你需要这样的东西吗?

    function rotateImage() {
            clip.rotation = 45;
            clip.fitInto(canvas.width, canvas.height);
        }
    

    https://codepen.io/EiseiKashi/pen/aGjbWK

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

    【讨论】:

    • 感谢您的建议,codepen 中的结果确实是我想要的,但我不想为此使用库。不过我会再看一下,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    • 2011-03-15
    • 2015-10-01
    相关资源
    最近更新 更多