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

问题:

用canvas绘制图片的时候会模糊,但是用img显示的时候就不会,canvas和img的大小是相同的 

至于为什么会变模糊,这和浏览器处理 canvas 的方式有关,相关的文章可以参考这篇 High DPI Canvas,这里不作深入介绍。

下面是相关的代码:

<!-- 通过 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>


解决问题思路:

先计算出设备实际宽度与页面之间的比例

比如,iphone 6 的就是双倍屏

那么我们就把 Canvas 的尺寸搞成双倍的,但是CSS样式尺寸搞成一倍的。

这就是核心思路

posterImg="a.jpg";
var canvas=document.createElement("canvas");
canvas.width=676;
canvas.height=984;
var ctx=canvas.getContext("2d");
// Canvas 在高清屏下绘制图片变模糊的解决方法
var devicePixelRatio = window.devicePixelRatio || 1;
var backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
    ctx.mozBackingStorePixelRatio ||
    ctx.msBackingStorePixelRatio ||
    ctx.oBackingStorePixelRatio ||
    ctx.backingStorePixelRatio || 1;
var ratio = devicePixelRatio / backingStoreRatio;
canvas.style.width = canvas.width + "px";
canvas.style.height = canvas.height + "px";
canvas.width = canvas.width * ratio;
canvas.height = canvas.height * ratio;
ctx.drawImage(posterImg, 0, 0, canvas.width, canvas.height);
ctx.save();


这个解决方案本质上是:

不管当前的devicePixelRatio的值是多少,统一将canvasDOM节点的width属性设置为其csswidth属性的两倍,同理将height属性也设置为cssheight属性的两倍

这样整个 canvas 的坐标系范围就扩大为两倍,但是在浏览器的显示大小没有变,canvas画图的时候,按照扩大化的坐系来显示,不清晰的问题就得以改善了