[英]Why do images lose quality after the context has been rotated?
我正在制作一个自上而下的射击游戏,依赖于头像始终旋转指向鼠标光标。 我像这样实现轮换:
//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
设置为非零值时(实际上,当它不是0
, Pi/2
, Pi
, Pi+Pi/2
或2Pi
),图像会失去它的清晰度,并且不再能看到单个像素,因为他们模糊了
这是一个截图(抱歉屏幕截图的一般质量不好,但我认为差异非常明显):
这有点令人无法接受。 我不能让图像总是模糊不清! 为什么会这样,我能解决吗?
你可以试试
context.imageSmoothingEnabled = false;
查看文档 :
context.imageSmoothingEnabled [= value]
返回模式填充和drawImage()方法是否会尝试平滑图像,如果它们必须重新缩放它们(而不是仅使用“大像素”渲染图像)。
可以设置,以更改图像是否平滑(true)与否(false)。
如果你想要一个真正的像素艺术复古风格效果,你需要手动创建几个角度的旋转精灵图像,查找适当的精灵为phi
的当前值,并绘制它而不旋转。 这显然需要大量的艺术作品!
如果围绕中心点旋转图像,请确保图像本身具有偶数个像素。 一旦最终得到奇数坐标,就需要为目标画布插入图像数据。 Apple 在翻译和旋转画布方面有一些很好的文档 。
因此,对于任何图像,如上所述,使用舍入来捕捉到全像素。
context.translate(Math.floor(img.width/2), Math.floor(img.height/2));
这样,图像的每个源像素将始终精确地绘制到画布内的像素中,并且不会出现模糊。 然而,这仅适用于90度的倍数。
似乎所有浏览器在某种程度上都在图像绘制中进行抗锯齿处理,因此您可能必须提供旋转图像作为精灵。
根据这个Chromium bug报告 ,如果他们尚未修复它,你可能会很幸运。 阅读并了解Ian Hickson可能会反对将抗锯齿图像绘制作为可选项。
(picture.width/2, picture.height/2)
点并不总是有效。
(Math.floor(picture.width/2) + 0.5, Math.floor(picture.height/2) + 0.5)
应该有帮助。
嗯,实际上这是你无法解决的问题
如果将图像旋转90度的倍数,则库应足够智能,以便不应用插值。
但是,只要将图像旋转不同于90度的倍数的角度,就需要进行插值。 结果,你得到了平滑。 如果您对该理论感兴趣,可以查找有关计算机图形或图像处理的书籍。
对于图像旋转的具体情况,您可以查看本文, http://bigwww.epfl.ch/publications/unser9502.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.