文章目录

Html5 canvas drawImage图片抗锯齿

虽然drawImage会自动应用消除锯齿,但如果是从大尺寸变为小尺寸,某些图像就不尽人意了,比如曲线。

对于可能的性能原因,浏览器似乎通常使用的是双线性(2×2采样)插值与画布元素而不是双立方(4×4采样)。

如果这个步骤太大,那么根本就没有足够的像素从结果中反映出来。

从signal/DSP的角度来看,可以将此看作是低通滤波器的阈值设置得太高,如果信号中有许多高频,则可能会导致混叠。

现在在specs中定义了一个新属性,用于设置重采样质量:

context.imageSmoothingQuality = "low|medium|high"

目前只有Chrome支持。每个级别使用的实际方法由供应商决定,但将Lanczos假设为“高”或质量相当的东西是合理的。

则可以完全跳过降级,或者根据图像大小和浏览器,更少的重绘可以使用较大的步骤。

解决方案是使用降压来获得正确的结果。降压意味着您可以逐步缩小尺寸,以允许有限的插值范围覆盖足够的像素进行采样。

这也可以在双线性插值的情况下得到很好的结果,这样做的时候,其实际上表现得更像是双立方体。

而且由于在每个步骤中采样的像素较少,所以开销很小。

理想的步骤是在每个步骤中使用分辨率的一半,直到设置到目标大小为止。

在原始问题中使用直接缩放

Html5 canvas drawImage抗锯齿

使用如下所示的降压

Html5 canvas drawImage抗锯齿

在这种情况下,需要分三步进行:

第一步,我们使用屏幕画布将图像缩小为一半:

/// step 1 - create off-screen canvas

var oc   = document.createElement('canvas'),
    octx = oc.getContext('2d');

oc.width  = img.width  * 0.5;
oc.height = img.height * 0.5;

octx.drawImage(img, 0, 0, oc.width, oc.height);

第二步,重新使用屏幕外画布,并将图像缩小到一半:

/// step 2
octx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5);

第三步,再次画主画布,又减半,但最终的大小:

/// step 3

ctx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5,0, 0, canvas.width,   canvas.height);

亲自测试一下

总结

您可以使用此公式计算所需的步骤总数(它包括设置目标大小的最后一步):

steps = Math.ceil(Math.log(sourceWidth / targetWidth) / Math.log(2))

本文网址:http://www.santii.com/article/197.html


数据更新时间:2018-11-14