我正在使用一个jquery插件来实用画布来绘制点动画动画。(http://arena.palamago.com.ar/spotMotion/)
我知道在这种情况下我可以使用动画GIF图像,但我将来使用的图像类型需要更高的质量和透明度。
如果你看下面的jsfiddle,你会看到图像不清晰,我在视网膜显示器上看起来更糟糕,原始图像是800px。由于某些未知原因,Canvas没有足够高地缩放图像。我对画布相当新,并且已经看到了一些扩展缩放的方法,但却没有获得更好的结果。
我查看了画布宽度和画布样式宽度
canvas.width = "200";
canvas.height = "200"; // allow 40 pixels for status bar on iOS
canvas.style.width = "100px";
canvas.style.height = "100px";
我还研究了css图像渲染技术
canvas { image-rendering:optimizeQuality;}
另一种尝试,但我似乎无法将其与此插件整合。
function enhanceContext(canvas, context) {
var ratio = window.devicePixelRatio || 1,
width = canvas.width,
height = canvas.height;
if (ratio > 1) {
canvas.width = width * ratio;
canvas.height = height * ratio;
canvas.style.width = width + "px";
canvas.style.height = height + "px";
context.scale(ratio, ratio);
}
}
我已经看到一些非常复杂的方法,人们编写扩展算法,我只是不明白如何把它放在一起。如果有人知道如何提高图像质量,请给我一些时间。
谢谢
答案 0 :(得分:2)
原因是源图像太大而无法在单个缩小范围内缩小尺寸。
当涉及到canvas元素时,浏览器通常使用双向插值而不是双三次插值。
双线性插值分析2x2像素,而双三次使用4x4(在下采样中用作低通滤波器以创建平均像素)。如果图像尺寸减小太陡,则根本没有足够的像素来考虑平均,结果将部分“波动”或像素化。
要解决此问题,您可以执行以下步骤之一:
在图像编辑器(例如Photoshop)中以较小的尺寸准备图像,并将图像缩放到您想要使用的目标尺寸(参见视网膜显示)。
在绘制之前在客户端处理图像,方法是创建一个离屏画布,然后按2-3步缩小图像。
由于各种原因,第一步可能是更好的解决方案,例如:
至于第二步:小提琴中有太多代码(TL; TR),但原理如下(并不是那么复杂):
/// create two temporary canvas elements
var ocanvas = document.createElement('canvas'), /// off-screen canvas
tcanvas = document.createElement('canvas'), /// temp canvas
octx = ocanvas.getContext('2d'),
tctx = ocanvas.getContext('2d');
然后我们对图像进行第一次降压缩放 - 对于这个例子,我们将做两次这是所需的最小值。如果尺寸差异很大,你可能需要第三步(你通常可以通过使用log等功能来计算它,但我会把它留在um之外,这里的“等式”):
/// use temp canvas (tcanvas) to scale for the first step
tcanvas.width = img.width * 0.5; /// 50% allow good result with bi-linear
tcanvas.height = img.height * 0.5;
/// draw image into canvas
tctx.drawImage(img, 0, 0, tcanvas.width, tcanvas.height);
下一步就像上面那样简单但绝对大小:
/// set destination size
ocanvas.width = 200;
ocanvas.height = 200;
/// draw temp canvas into canvas
octx.drawImage(tcanvas, 0, 0, ocanvas.width, ocanvas.height);
您现在可以在解决方案中使用ocanvas
而不是img
。
我们使用两个画布,因为我们希望稍后使用最终的ocanvas
直接替换img
以适当的大小。如果我们使用一个画布,我们将不得不在最后一步调整它,这意味着画布将被清除。
如果您确实需要第三步,那么您可以重复使用其中一幅画布。
这里的附加优势是浏览器在动画时无需缩放任何内容,从而减少了CPU / GPU的负担。
我建议在函数内部执行此缩减操作,以便在使用后浏览器可以轻松地丢弃临时画布引用(您需要使用的pf课程除外)(GC /内存)明智)。
希望这有帮助!