1. 程式人生 > >Canvas 在高清屏下繪製圖片變模糊的解決方法

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>

解決問題:

其實,不只是繪製圖片時會出現模糊的問題,正常情況下,在高清屏的裝置下,任何繪製canvas中的圖形(包括文字)都會出現模糊的問題。上面這個就是為了解決這個問題,但是他沒有處理圖片。

接下來,修改繪製圖片的程式碼

將 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);
}
這個解決方案本質上是:

不管當前的devicePixelRatio的值是多少,統一將canvasDOM節點的width屬性設定為其csswidth屬性的兩倍,同理將height屬性也設定為cssheight屬性的兩倍,即:

<canvas width="320" height="180" style="width:160px;height:90px;"></canvas>

這樣整個 canvas 的座標系範圍就擴大為兩倍,但是在瀏覽器的顯示大小沒有變,canvas畫圖的時候,按照擴大化的坐系來顯示,不清晰的問題就得以改善了