Javascript spot运动画布动画中的低质量图像
我正在使用一个jquery插件,该插件可以使用画布绘制点运动动画。() 我知道,在这种情况下,我可以使用动画GIF图像,但我在未来使用的图像类型将需要更高的质量和透明度 如果你看下面的JSFIDLE,你会看到图像不清晰,我在视网膜显示器上,它们看起来更糟,原始图像是800px。画布缩放图像的高度不够高,原因不明。我对canvas还相当陌生,见过一些放大的方法,但没有运气得到更好的结果 我查看了画布宽度和画布样式宽度Javascript spot运动画布动画中的低质量图像,javascript,html,animation,canvas,Javascript,Html,Animation,Canvas,我正在使用一个jquery插件,该插件可以使用画布绘制点运动动画。() 我知道,在这种情况下,我可以使用动画GIF图像,但我在未来使用的图像类型将需要更高的质量和透明度 如果你看下面的JSFIDLE,你会看到图像不清晰,我在视网膜显示器上,它们看起来更糟,原始图像是800px。画布缩放图像的高度不够高,原因不明。我对canvas还相当陌生,见过一些放大的方法,但没有运气得到更好的结果 我查看了画布宽度和画布样式宽度 canvas.width = "200"; canvas.height = "2
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(在下采样中用作低通滤波器以创建平均像素)。如果图像尺寸减小太陡,则没有足够的像素来考虑平均值,结果将部分地“起伏”或像素化。
解决方案
要解决此问题,可以执行以下步骤之一:
- 在客户端上不会处理图像(大小)
- 结果图像的质量(更易于后期处理)
- 带宽减少(要传输的数据减少)
- 在客户端上更快地处理图像(正在使用)
- 节省电池(所需处理更少)
/// 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);