我使用transform: scale(x)
缩小了我真棒图形编辑器的内容。当缩小比例向下0
(不包括)时,当放大比例上升时,最大为1
(包括),这意味着完全缩放或初始比例。
然而,当缩小时,图像质量开始变得非常嘈杂 - 请考虑以下示例,并注意缩小将如何使图像外观嘈杂:
var graphContainer = document.getElementById("graph-container");
var zoomInButton = document.getElementById("zoom-in-button");
var zoomOutButton = document.getElementById("zoom-out-button");
var zoomLevel = 1;
zoomInButton.addEventListener("click", function () {
zoomLevel = Math.max(1, zoomLevel - 0.25);
graphContainer.style.transform = "scale(" + (1 / zoomLevel) + ")";
});
zoomOutButton.addEventListener("click", function () {
zoomLevel = zoomLevel + 0.25;
graphContainer.style.transform = "scale(" + (1 / zoomLevel) + ")";
});

#editor-container {
background-color: #001723;
}
#graph-container { transform-origin: top center; }

<div id="editor-container">
<button id="zoom-in-button">Zoom in</button>
<button id="zoom-out-button">Zoom out</button>
<div id="graph-container">
<img class="shape" src="http://i.imgur.com/zsWkcGz.png" />
</div>
</div>
&#13;
此图像是画布绘制的形状,以交互方式显示两个图形节点之间的连接,导出到png。
请缩小并查看该线的噪音,即使以0.25
和CSS的步长进行缩放也是如此。 如何摆脱这种像素噪音?最新的Google Chrome和Microsoft Edge都存在问题,而在其他浏览器中未经测试。无论有没有3D GPU加速,都会出现问题。
注意:显然,这是一个Minimal, Complete, and Verifiable example,真正的工作量更复杂。
线条形状的渐变在程序上绘制到画布上(每行<1ms),然后在空闲时使用toDataUrl(每行约40ms)异步缓存到
img
个元素,以便屏幕平移 - 这也是必需的功能 - 工作更顺利,因为在屏幕上移动img
元素比移动canvas
元素(或重绘单个画布上的所有线条)便宜得多,无论是它是转换为给定方向的元素本身,容器或浏览器视口。因此,生成mipmap实际上不是一种选择,或仅作为最后的手段,因为它会带来重要的性能损失(每个mip级别会必须将其缓存到单独的图像上,至少将性能降低一半)。不过,我想相信它可以避免。在每个缩放步骤中重新绘制线条形状将巧妙地消除性能直至幻灯片放映。
以下是我尝试过的事情清单,没有效果:
image-rendering: pixelated | optimizeSpeed | optimizeQuality
transform
scale3d
代替scale
img.width
和img.height
减半,然后加倍img.style.width
和img.style.height
img
,而是直接显示canvas
元素(效果较差,质量相同)我在缩小时也尝试使用filter: blur
,但是did not yield a better quality,因为在已经在屏幕上呈现给定的形状后,应用了模糊效果本身。
除了创建每个形状的缩减采样版本,还能有效地创建一个软件渲染的mipmap(LOD)系统,我还能做些什么才能摆脱这种像素噪声?(正如我所写的那样) ,希望强烈避免)
这个问题与similar questions从缩小尺度调查不良图像质量的数组有什么不同?
答案 0 :(得分:3)
使用SVG图像而不是PNG可以获得更好的效果,并且它们也很容易生成并嵌入到您的代码中,您甚至不需要托管它们。
正如你在demo中看到的那样,SVG不会像素化或变得模糊,你会在像Retina这样的高分辨率屏幕上获得更好的效果。
SVG代码:
<svg class="shape" width="440px" height="319px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M1,316.040132 C1,316.040132 241.5837,339.680482 241.5837,163.497447 C241.5837,-12.6855883 439,2.31775322 439,2.31775322" id="Path" stroke="#50E3C2" stroke-width="2"></path>
</g>
</svg>
显然不完美。
答案 1 :(得分:2)
具有锐边的图像的插值将不可避免地产生伪影。即使它是抗污染的,即使它是模糊的。你可以在Photoshop中测试它,你会得到相同的结果。
即使是mipmap方法也行不通。
固有的问题是像素无法保留复杂矢量形状的所有信息;当你挤压像素时,形状会丢失。有两种解决方案可以提高质量: