解決canvas畫圖模糊的問題


canvas 畫圖經常發現他是模糊的。解決這個問題主要從兩個方面下手。

  1. 改變canvas渲染的像素
    情況:畫1像素的線條看起來模糊不清,好像更寬的樣子。

clipboard.png
解決方案

var ctx = canvas.getContext('2d');
ctx.translate(0.5, 0.5);

原理:大家都知道屏幕最小單位就是像素。假如把canvas放的足夠大,我能看到下面樣子。

clipboard.png

每一個方格就是長和寬都為1px。當我們畫1px線條時遵循像素的起止范圍,我們能得到標准的細線。

clipboard.png
但遺憾的是canvas的畫法不一樣。canvas的每條線都有一條無限細的“中線”,線條的寬度是從中線向兩側延伸的。如果我們還是從第2個像素點畫一條線,那么線條的中線就會靠齊到第2個像素的起點,然后我們開始畫了,問題也就來了:Canvas 的線條以中線向兩側延伸,而不是向某一邊延伸(比如這里,如果只是往右側延伸,那么我們的問題就不再是問題了),延伸過后我們的線條實際上是這樣的:

clipboard.png
但是計算機不允許出現<1px的圖形。所以會做個折中,把兩個像素都繪制了。如此一來,本來1px的線條,就成了看起來2px寬的線條。
如何解決這個問題,就是把線條中線和和像素中間點對齊就行了。

clipboard.png
中間點位置很好找,向后移動0.5px。所以你們畫線時可以這樣:

ctx.moveTo(100.5,100.5);
ctx.lineTo(200.5,100.5);
ctx.lineTo(200.5,200.5);
ctx.lineTo(100.5,200.5);
ctx.lineTo(100.5,100.5);

或者

ctx.translate(0.5, 0.5);

2.設置顯示比例
在瀏覽器的window變量中有一個devicePixelRatio的屬性,該屬性決定了瀏覽器會用幾個(通常是2個)像素點來渲染1個像素,舉例來說,假設某個屏幕的devicePixelRatio的值為2,一張100x100像素大小的圖片,在此屏幕下,會用2個像素點的寬度去渲染圖片的1個像素點,因此該圖片在此屏幕上實際會占據200x200像素的空間,相當於圖片被放大了一倍,因此圖片會變得模糊。
**其實方案很簡單,也很容易明白。我們可以創建一個兩倍於實際大小的canvas,然后用css樣式把canvas限定在實際的大小。
下面是實現具體代碼例子:

var canvas = document.getElementById("canvas")
        context= canvas.getContext("2d");  
    var devicePixelRatio = window.devicePixelRatio || 1;
    var backingStoreRatio = context.webkitBackingStorePixelRatio ||
                        context.mozBackingStorePixelRatio ||
                        context.msBackingStorePixelRatio ||
                        context.oBackingStorePixelRatio ||
                        context.backingStorePixelRatio || 1;
    var ratio = devicePixelRatio / backingStoreRatio;
    canvas.width = canvas.width * ratio;
    canvas.width = canvas.height* ratio;
    context.scale(ratio, ratio);
    ctx.translate(0.5, 0.5);
    ctx.lineWidth = 1;
    ctx.moveTo(2.5, 2);
    ctx.lineTo(98.5, 2);
    ctx.lineTo(98.5, 98);
    ctx.lineTo(2.5, 98);
    ctx.lineTo(2.5, 2);
    ctx.stroke();

原來具體詳細解釋:請看這里


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM