【问题标题】:How to rotate image - canvas pixel manipulation?如何旋转图像 - 画布像素操作?
【发布时间】:2016-03-24 13:29:35
【问题描述】:

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

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

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


jsfiddle demo

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


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

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

【问题讨论】:

  • 我正在快速检查旧项目,但现在我不确定我是如何处理它的。我知道我确实做出了一些妥协,并在其他领域提升了性能。我认为我使用的其中一件事是将每个新的程序创建的图像预渲染到它自己的画布中,并使用标准的画布旋转功能来获取该特定对象的动画所需的所有帧。基本上,我尽可能提前准备好精灵,同时确保我摧毁其他无法重新利用的精灵。
  • 没关系,我得到了中间的白色/空白像素,不知道该怎么办,我无法解决并从我的画布游戏中移除旋转。
  • 好吧,我建议你简单地使用画布旋转。它非常有效,如果您使用硬件加速,除非您进入大量的精灵,否则您根本不会感觉到它。不过,我会首先检查您是否可以使用一个大画布并保存 - 反式 - 腐烂 - 休息例程或仅针对每个精灵使用几个较小的画布来获得更好的结果 - 或者至少为不同大小的图像设置几个单独的画布 -并使用相同的程序将它们旋转到那里,然后从这些画布中绘制到您的主要画布中(我认为每张图像的画布会产生更快的结果)。

标签: javascript canvas image-rotation


【解决方案1】:

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

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

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

【讨论】:

  • ...你的照片值一千字,好清晰的答案!
  • 谢谢,我也是这么想的,虽然,我应该多强调一下,性能是这里的关键。我正在使用 2d 画布,因此在这种情况下,步骤/计算的数量会显着减少 10000 个粒子的动画。但我仍在试图找出一种方法,我猜一条路一半一半另一条路;-)。无论如何,非常感谢您向我保证这种观点是真正鼓舞士气的方法:-)。
  • 如果性能是您最关心的问题,我希望内置功能(save -> translate -> rotate -> restore)实际上是您最快的get 因为内置函数的实现不仅限于 javascript,还可以利用硬件功能。当然,无论如何,您都可以采取一些简单的技巧来提高性能,例如只允许 N 个可能的旋转角度,然后将相同的旋转图像粘贴到所有不同的地方。如果您有 10,000 张不同的图片,您将不得不尝试其他方法。
  • 是的,我实际上正在做与您刚才提到的类似的事情,但是当我使用您提到的画布方法时,我几乎无法绘制数千个运动的粒子。但是我正在把你提到的所有东西放在一起,然后把它和其他东西结合起来,如果能解决的话,但我以前从来没有这样做过,所以我碰壁的次数比我想的要多:-)。谢谢你的建议。
猜你喜欢
  • 1970-01-01
  • 2011-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-01
  • 2020-07-11
  • 2016-01-12
  • 1970-01-01
相关资源
最近更新 更多