Canvas 在高清屏下绘制图片变隐约的解决方法

之前我在 SF 上回复过「html5 canvas绘制图片隐约的题目」,然则多是因为我给出的答案过于简朴,加上答案中的 demo 链接已失效,很多人反应这类要领并不好使。然则我在给出答案之前是在小米2 和 iPhone 上测试过的,没有任何题目。下面我会一步一步地形貌详细的步骤。

前提条件

假定我们要在 canvas 中绘制一张 300 x 90 的图片,而且要保证它在高清屏中不隐约。那末我们起首要预备一张 600 x 180 的图片,处置惩罚太高清屏的同砚应当会有这方面的履历。

题目重现

OK,我们先把题目重现一下,以便有一个更直观的相识。下面是相干的代码(为了简朴起见,我把代码都写在了 HTML 文档内里):

<!-- 经由过程 img 标签引入图片,以便绘制到 canvas 中 -->
<img src="html5rocks.png" alt="" width="300" height="90">

<!-- canvas -->
<canvas width="300" height="90"></canvas>

<script>
    function init() {
        var canvas = document.querySelector('canvas');
        var ctx = canvas.getContext('2d');
        ctx.drawImage(document.querySelector('img'), 0, 0, 300, 90);
    }
    window.onload = init;
</script>

代码很简朴,没有做任何处置惩罚,详细的结果和完全的代码能够检察这个 DEMO,这个 demo 在高清屏的手机中会涌现的题目:canvas 中的图片变隐约了!。

至于为何会变隐约,这和浏览器处置惩罚 canvas 的体式格局有关,相干的文章能够参考这篇 High DPI Canvas,这里不作深切引见。

处理题目

起首,引入 hidpi-canvas-polyfill

实在,不只是绘制图片时会涌现隐约的题目,一般情况下,在高清屏的装备中,任何绘制在 canvas 中的图形(包含笔墨)都邑涌现隐约的题目。上面这个 polyfill 就是为相识决这个题目,然则它没有处置惩罚图片。

接下来,修正绘制图片的代码

init 函数修正成下面如许:

function init() {
    var canvas = document.querySelector('canvas');
    var ctx = canvas.getContext('2d');

    // polyfill 供应了这个要领用来猎取装备的 pixel ratio
    var getPixelRatio = function(context) {
        var backingStore = context.backingStorePixelRatio ||
            context.webkitBackingStorePixelRatio ||
            context.mozBackingStorePixelRatio ||
            context.msBackingStorePixelRatio ||
            context.oBackingStorePixelRatio ||
            context.backingStorePixelRatio || 1;
    
        return (window.devicePixelRatio || 1) / backingStore;
    };

    var ratio = getPixelRatio(ctx);
    
    // 注重,这里的 width 和 height 变成了 width * ratio 和 height * ratio
    ctx.drawImage(document.querySelector('img'), 0, 0, 300 * ratio, 90 * ratio);
}

能够点击这里检察完全的代码和结果,在高清屏的装备中翻开,看看 cavans 中的图片是不是圆满显现。

申明

这个处理方案本质上和 @白一梓 的答案是一样的:先放大 canvas,再用 CSS 将其限定回原始大小。

假如你看了 polyfill 的代码就会邃晓个中的原理了,这个 polyfill 的代码非常简短清楚明了,它做了两件事:一是将 canvas 的高和宽离别乘以 ratio 将其放大,然后又用 CSS 将高和脱期定成初始的大小;二是 hack canvas 中经常运用的函数,如:fillRect, clearRect, lineTo, arc 等,将它们的参数都乘以 ratio,以轻易我们能够像之前那样运用这些要领,而不用在传参的时刻手动乘以 ratio。

    原文作者:KevinYue
    原文地址: https://segmentfault.com/a/1190000003730246
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞