按canvas旋转后的图像裁剪

我有一个html5canvas。 我想在canvas上绘制/旋转图像,图像大小不会改变。我根据图像的大小设置canvas的宽度/高度。旋转图像时出现问题。旋转图像后,红色三角形被裁剪。 在下面链接一个示例显示这个问题。请帮助。 http://jsfiddle.net/zsh64/6ZsCz/76/

var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var angleInDegrees = 0; var image = document.createElement("img"); image.onload = function () { canvas.width = image.width; canvas.height = image.height; ctx.drawImage(image, 0,0); }; image.src = "Images/rotate.png"; $("#R").click(function () { angleInDegrees += 90; drawRotated(angleInDegrees); }); $("#L").click(function () { angleInDegrees -= 90; drawRotated(angleInDegrees); }); function drawRotated(degrees) { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.save(); ctx.translate(canvas.width / 2, canvas.height / 2); ctx.rotate(degrees * Math.PI / 180); ctx.drawImage(image, -image.width / 2, -image.width / 2); ctx.restore(); } 

如果旋转图像,则可以重新计算包含图像所需的边界框。

在此处输入图像描述在此处输入图像描述

此代码将采用宽度/高度/旋转角度并返回新的边界框大小:

 function newSize(w,h,a){ var rads=a*Math.PI/180; var c = Math.cos(rads); var s = Math.sin(rads); if (s < 0) { s = -s; } if (c < 0) { c = -c; } size.width = h * s + w * c; size.height = h * c + w * s ; } 

这是示例代码和小提琴: http : //jsfiddle.net/m1erickson/h65yr/

             

问题

您面临两个问题:

  1. canvas上没有足够的空间来进行旋转
  2. 您正在旋转中心而不是图像中心绘制图像

解决方案

要正确调整canvas大小,可以使用旋转矩形的最大边界。 要找到这个边界,你可以做以下两件事之一:

如果您只需要每90度旋转一次:

 var length = Math.max(img.width, img.height); 

如果你想使用自由角度:

 var length = Math.sqrt(img.width * img.width + img.height * img.height); 

然后使用以下结果之一来设置canvas的大小:

 canvas.width = canvas.height = length; /// both has same length 

接下来要正确地绘制图像。 旋转后,您需要转换回来,因为图像始终从其左上角绘制:

 var pivot = length * 0.5; ctx.save(); ctx.translate(pivot, pivot); ctx.rotate(degrees * Math.PI / 180); ctx.drawImage(image, -image.width * 0.5, -image.height * 0.5); ctx.restore(); 

重要的是你使用图像的轴将其偏移回来,因为图像在这里的尺寸与canvas不同。

这个现场演示的结果如下:

旋转矩形的界限

更改drawImage的参数

 ctx.drawImage(image, -image.width / 2, -image.height/ 2);