如何旋转图像 - canvas 像素操作?

How to rotate image - canvas pixel manipulation?

我使用 getImageData 和 putImageData 从缓冲区 canvas 绘制 canvas。我使用这些方法是因为我有大量的粒子,并且这些方法被证明可以提供最佳性能。 现在我想添加粒子旋转,但我遇到了问题。 这是一个 jsfiddle ,它使用变换矩阵进行旋转。正如您在图片(或 fiddle)中看到的那样,生成的图像中存在漏洞,我有点希望使用此矩阵。

nx = ~~ (xx * Math.cos(angle) + yy * Math.sin(angle) + cx);
ny = ~~ (xx * Math.sin(angle) - yy * Math.cos(angle) + cy);

但我不知道如何让它变得更好,尤其是当我正在寻找性能高效的解决方案时?


jsfiddle demo

图像-旋转后的正方形(正方形用作简体):


目前我的备份是程序生成的精灵动画,它是预先准备好的标准canvas状态:保存 -> 翻译 -> 旋转 -> 恢复。

非常感谢您给我的任何指示。

问题是您试图将单个像素映射到单个像素。旋转图像时,原始图像中的每个像素都会影响新图像中的任何周围像素。您有效地将每个像素的左上角映射到它在新图像中的位置,但是您需要将每个像素的中心映射到它在新图像中的位置,然后检查该旋转像素与该位置的重叠,以及新图像中的 8 个周围像素。

到这里就可以看到效果了。黄点是像素的中心,它找到像素的 "home" 位置(即大部分影响将放置的位置)。然后,您需要计算出该像素(底层 blue/white 网格)单元格被原始像素(黄点周围的黑框)覆盖的百分比。一旦确定了家庭位置的影响,就需要针对原始图像中当前像素的 8 个周围像素重复该过程。在您当前的代码中,您使用每个像素的左上角来查找新图像的主像素。你应该使用像素的中心。

由于多次迭代可能会影响同一个像素,因此您需要先计算缓冲区中的变换,然后再将其绘制为最终图像。对于转换中未被原始图像中的像素完全覆盖的像素,计算出被覆盖像素的百分比并使用它来影响 alpha 通道。将像素应用于最终图像时,您必须小心,因为您考虑了 alpha 部分并与已经存在的部分混合。