上下文旋转后为什么图像质量下降?

时间:2012-07-05 20:55:48

标签: javascript image canvas browser

我正在制作一个自上而下的射击游戏,它依赖于始终旋转指向鼠标光标的头像。我实现了这样的轮换:

//Rendering.
context.save(); //Save the context state, we're about to change it a lot.

context.translate(position[0] + picture.width/2, position[1] + picture.height/2); //Translate the context to the center of the image.
context.rotate(phi); //Rotate the context by the object's phi.
context.drawImage(picture.image, -picture.width/2, -picture.height/2); //Draw the image at the appropriate position (center of the image = [0, 0]).

context.restore(); //Get the state back.

phi为零时,图像以正常质量渲染,具有锐边和可检测像素。但是,当我将phi设置为非零值时(实际上,当它不是0Pi/2PiPi+Pi/22Pi时),图像失去了它的清晰度,不再能看到单个像素,因为它们模糊了。

这是一个屏幕截图(对于屏幕截图的一般质量不好而感到抱歉,但我认为差异非常明显):

enter image description here

这是有点不可接受的。我不能让图像总是模糊不清! 为什么会发生这种情况,我可以解决吗?

4 个答案:

答案 0 :(得分:17)

你可以尝试

context.imageSmoothingEnabled = false;

请参阅docs

  

context.imageSmoothingEnabled [= value]

     

返回图案填充和drawImage()方法是否会尝试平滑图像(如果必须重新缩放图像)(而不是仅使用“大像素”渲染图像)。

     

可以设置,更改图像是否平滑(true)与否(false)。

如果你想要一个真正的像素艺术复古风格效果,你需要手动创建几个角度的旋转精灵图像,查找适当的精灵为当前值phi,并绘制它而不旋转。这显然需要大量的艺术作品!

答案 1 :(得分:3)

如果围绕中心点旋转图像,请确保图像本身具有偶数个像素。一旦最终得到奇数坐标,就需要为目标画布插入图像数据。 Apple有一些不错的documentation on translating and rotating the canvas

因此,对于任何图像,如上所述,使用舍入来捕捉全像素。

context.translate(Math.floor(img.width/2), Math.floor(img.height/2));

这样,图像的每个源像素将始终精确地绘制到画布内的像素中,并且不会出现模糊。然而,这仅适用于90度的倍数。

似乎所有浏览器在某种程度上都在图像绘制中进行抗锯齿处理,因此您可能必须提供旋转图像作为精灵。

根据这个Chromium bug report你可能很幸运,如果他们还没有解决它。通读后,您将了解Ian Hickson可能反对将抗锯齿图像绘制选项。

答案 2 :(得分:1)

(picture.width/2, picture.height/2)点不会一直有效。

(Math.floor(picture.width/2) + 0.5, Math.floor(picture.height/2) + 0.5)应该有帮助。

答案 3 :(得分:0)

嗯,实际上这是你无法解决的问题

如果您将图像旋转90度的倍数,您的库应该足够智能,以便不应用插值。

但是,只要将图像旋转不同于90度的倍数的角度,就需要进行插值。结果,你得到了平滑。如果你对这个理论感兴趣,你可能会找一本关于计算机图形学或图像处理的书。

对于图像旋转的具体情况,您可以查看本文, http://bigwww.epfl.ch/publications/unser9502.html