23

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

//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为 0 时,图像以其正常质量呈现,具有锐利的边缘和可检测的像素。但是,当我将 设置phi为非零值时(实际上,当它不是0Pi/2、或时) Pi,图像会失去其清晰度,并且无法再看到单个像素,因为它们被模糊了。Pi+Pi/22Pi

这是一个屏幕截图(很抱歉屏幕截图的质量一般很差,但我认为差异非常明显):

在此处输入图像描述

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

4

4 回答 4

17

你可以试试

context.imageSmoothingEnabled = false;

请参阅文档

context.imageSmoothingEnabled [ = value ]

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

可以设置,以更改图像是否平滑(真)或不(假)。

如果您想要一个真正的像素艺术复古风格效果,您需要手动创建多个角度的旋转精灵图像,查找当前值的适当精灵phi,并在不旋转的情况下绘制它。这显然需要相当多的艺术作品!

于 2012-07-14T19:08:07.067 回答
3

如果您要围绕其中心点旋转图像,请确保图像本身具有偶数个像素。一旦你最终得到奇坐标,就需要为目标画布插入图像数据。Apple 有一些关于翻译和旋转画布的不错的文档。

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

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

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

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

根据这个Chromium 错误报告,如果他们还没有修复它,你可能会很幸运。通读一遍,您将了解到 Ian Hickson 可能反对将抗锯齿图像绘制作为可选选项。

于 2012-07-18T12:41:13.160 回答
1

(picture.width/2, picture.height/2)点并不总是有效。

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

于 2012-07-06T09:32:43.550 回答
0

好吧,实际上这是您无法解决的问题

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

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

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

于 2012-07-20T08:02:20.717 回答