Javascript spot运动画布动画中的低质量图像

Javascript spot运动画布动画中的低质量图像,javascript,html,animation,canvas,Javascript,Html,Animation,Canvas,我正在使用一个jquery插件,该插件可以使用画布绘制点运动动画。() 我知道,在这种情况下,我可以使用动画GIF图像,但我在未来使用的图像类型将需要更高的质量和透明度 如果你看下面的JSFIDLE,你会看到图像不清晰,我在视网膜显示器上,它们看起来更糟,原始图像是800px。画布缩放图像的高度不够高,原因不明。我对canvas还相当陌生,见过一些放大的方法,但没有运气得到更好的结果 我查看了画布宽度和画布样式宽度 canvas.width = "200"; canvas.height = "2

我正在使用一个jquery插件,该插件可以使用画布绘制点运动动画。()

我知道,在这种情况下,我可以使用动画GIF图像,但我在未来使用的图像类型将需要更高的质量和透明度

如果你看下面的JSFIDLE,你会看到图像不清晰,我在视网膜显示器上,它们看起来更糟,原始图像是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);
   }
} 
我看到过一些非常复杂的方法,人们编写了放大算法,我只是不知道如何把它们组合起来。如果有人知道如何提高图像质量,请给我一些时间

谢谢

问题 原因是源图像太大,无法在单个缩小范围内缩小

对于画布元素,浏览器通常使用双线性插值而不是双立方插值

双线性插值分析2x2像素,而双立方使用4x4(在下采样中用作低通滤波器以创建平均像素)。如果图像尺寸减小太陡,则没有足够的像素来考虑平均值,结果将部分地“起伏”或像素化。

解决方案 要解决此问题,可以执行以下步骤之一:

  • 在图像编辑器(例如Photoshop)中以较小的尺寸准备图像,并将图像缩放到您想要使用的目标尺寸(参考视网膜显示)

  • 在客户机上处理图像,然后通过创建屏幕外画布绘制图像,并分2-3步缩小图像

  • 出于各种原因,第一步可能是更好的解决方案,例如:

    • 在客户端上不会处理图像(大小)
    • 结果图像的质量(更易于后期处理)
    • 带宽减少(要传输的数据减少)
    • 在客户端上更快地处理图像(正在使用)
    • 节省电池(所需处理更少)
    至于第二步:fiddle(TL;TR)中的代码太多了,但原则如下(并且没有那么复杂):

    然后我们对图像进行第一步的缩放-在本例中,我们将进行两次,这是所需的最小值。如果尺寸差异很大,您可能需要第三步(您通常可以使用log等函数来计算,但我不在这里的“等式”中):

    下一步与上述步骤一样简单,但具有绝对大小:

    /// 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 course的引用除外,需要返回该引用)在使用后(GC/内存方面)可以很容易地被浏览器丢弃


    希望这有帮助

    SVG+CSS动画?可以工作,但我想将其应用于更详细的动画,比如角色行走或树木赚钱。像卡通一样的东西,我觉得这有点超出SVG?请记住,我也可以使用GIF来实现这一点,但这是一个更重要的原则,我想提高画布绘制图像的比例。SVG可能很复杂。将图像的所有子对象显示为SVG。这个综合体?是啊,为什么不呢?只是一堆渐变、贝塞尔曲线和路径。
    /// 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);