如何在HTML5画布上使用更好的插值来缩放图像?

7 浏览
0 Comments

如何在HTML5画布上使用更好的插值来缩放图像?

首先,我想做什么?

我有一个查看图片的应用程序。它使用canvas元素渲染图像。您可以放大,缩小和拖动图像。这部分目前运行得非常完美。

但是假设我有一张有很多文字的图像。它的分辨率是1200x1700,而我的canvas为1200x900。初始状态下,当缩小时,它导致渲染分辨率约为560x800。

我的实际绘图如下所示:

drawImage(src,srcOffsetX,srcOffsetY,sourceViewWidth,sourceViewHeight,
destOffsetX,destOffsetY,destWidth,destHeight);

这张图上的小文字看起来非常糟糕,特别是与其他图片查看器(如IrfanView)或甚至是html 元素相比。

我发现浏览器的插值算法是这个问题的原因。比较不同的浏览器显示,Chrome呈现的缩放图像最好,但仍然不够好。

好吧,我在整个互联网上搜索了4-5个小时,但没有找到我需要的东西。我找到了“imageSmoothingEnabled”选项,“image-rendering”CSS样式,但无法在canvas上使用,以及在浮点位置上进行渲染和许多插值算法的JavaScript实现(这些实现对我的目的来说太慢了)。

您可能会问我为什么告诉您所有这些:为了节省您给我已经知道的答案所需的时间。

那么:有没有任何好的快速方法来改善插值?我目前的想法是创建一个图像对象,重新调整大小(因为缩放时img具有良好的插值!),然后再渲染它。不幸的是,应用img.width似乎只影响显示的宽度...

更新:感谢Simon,我解决了我的问题。

这是我使用的动态缩放算法。请注意,它保持宽高比,高度参数仅用于避免更多的浮点计算。它目前只进行缩小。

scale(destWidth, destHeight){
        var start = new Date().getTime();
        var scalingSteps = 0;
        var ctx = this._sourceImageCanvasContext;
        var curWidth = this._sourceImageWidth;
        var curHeight = this._sourceImageHeight;
        var lastWidth = this._sourceImageWidth;
        var lastHeight = this._sourceImageHeight;
        var end = false;
        var scale=0.75;
        while(end==false){
            scalingSteps +=1;
            curWidth *= scale;
            curHeight *= scale;
            if(curWidth < destWidth){
                curWidth = destWidth;
                curHeight = destHeight;
                end=true;
            }
            ctx.drawImage(this._sourceImageCanvas, 0, 0, Math.round(lastWidth), Math.round(lastHeight), 0, 0, Math.round(curWidth), Math.round(curHeight));
            lastWidth = curWidth;
            lastHeight = curHeight;
        }
        var endTime =new Date().getTime();
        console.log("execution time: "+ ( endTime - start) + "ms. scale per frame: "+scale+ " scaling step count: "+scalingSteps);
    }

0