簡體   English   中英

HTML5 - Canvas, drawImage() 繪制圖像模糊

[英]HTML5 - Canvas, drawImage() draws image blurry

我正在嘗試將以下圖像繪制到畫布上,但盡管定義了畫布的大小,但它仍然顯得模糊。 正如您在下面看到的,圖像清晰而清晰,而在畫布上,它是模糊和像素化的。

在此處輸入圖片說明

這是它的外觀(左邊的是原始的,右邊的是畫布上的,並且很模糊。)

在此處輸入圖片說明

我究竟做錯了什么?

 console.log('Hello world') var c = document.getElementById('canvas') var ctx = c.getContext('2d') var playerImg = new Image() // http://i.imgur.com/ruZv0dl.png sees a CLEAR, CRISP image playerImg.src = 'http://i.imgur.com/ruZv0dl.png' playerImg.width = 32 playerImg.height = 32 playerImg.onload = function() { ctx.drawImage(playerImg, 0, 0, 32, 32); };
 #canvas { background: #ABABAB; position: relative; height: 352px; width: 512px; z-index: 1; }
 <canvas id="canvas" height="352" width="521"></canvas>

發生這種情況的原因是抗鋸齒。 只需像這樣將imageSmoothingEnabled設置為 false

context.imageSmoothingEnabled = false;

這是一個 jsFiddle 版本

jsFiddle: https ://jsfiddle.net/mt8sk9cb/

var c = document.getElementById('canvas')
var ctx = c.getContext('2d')
var playerImg = new Image()

// http://i.imgur.com/ruZv0dl.png sees a CLEAR, CRISP image
playerImg.src = 'http://i.imgur.com/ruZv0dl.png'

playerImg.onload = function() {
  ctx.imageSmoothingEnabled = false;
  ctx.drawImage(playerImg, 0, 0, 256, 256);
};

您的問題是canvas{width:512}與 canvas 屬性width=521的 css 約束將使您的瀏覽器重新采樣整個畫布。

為避免這種情況,請刪除那些 css 聲明。

 var c = document.getElementById('canvas') var ctx = c.getContext('2d') var playerImg = new Image() // http://i.imgur.com/ruZv0dl.png sees a CLEAR, CRISP image playerImg.src = 'http://i.imgur.com/ruZv0dl.png' playerImg.width = 32 playerImg.height = 32 playerImg.onload = function() { ctx.drawImage(playerImg, 0, 0, 32, 32); };
 #canvas { background: #ABABAB; position: relative; z-index: 1; }
 <canvas id="canvas" height="352" width="521"></canvas>

此外,如果您要重新采樣圖像(從 32x32 到其他尺寸),@canvas 的解決方案將是可行的方法。

當我針對我的一些問題遇到這篇較舊的帖子時,這里有更多關於模糊圖像的更多見解,以便在“imageSmoothingEnabled”解決方案之上進行分層。

這更具體地用於監視器特定渲染的用例,如果他們一直試圖將視網膜質量的圖形渲染到他們的畫布中,結果令人失望,那么只有一些人會遇到這個問題。

從本質上講,高密度顯示器意味着您的畫布需要容納額外的像素密度。 如果你什么都不做,你的畫布只會將足夠的像素信息渲染到它的上下文中,以說明像素比為 1。

因此,對於比率 > 1 的許多現代顯示器,您應該更改畫布上下文以考慮這些額外信息,但保持畫布的正常寬度和高度。

為此,您只需將渲染上下文的寬度和高度設置為:目標寬度和高度 * window.devicePixelRatio。

canvas.width = target width * window.devicePixelRatio;
canvas.height = target height * window.devicePixelRatio;

然后設置畫布的樣式以按正常尺寸調整畫布的大小:

canvas.style.width = `${target width}px`;
canvas.style.height = `${target height}px`;

最后以圖像允許的最大上下文大小渲染圖像。 在某些情況下(例如圖像渲染 svg),您仍然可以通過以 pixelRatio 大小的尺寸渲染圖像來獲得更好的圖像質量:

ctx.drawImage(
    img, 0, 0, 
    img.width * window.devicePixelRatio, 
    img.height * window.devicePixelRatio
  );

所以為了炫耀這種現象,我做了一個小提琴。 如果您在像素比率接近 1 的顯示器上,您將看不到畫布質量的差異。

https://jsfiddle.net/ufjm50p9/2/

除了@canvas 答案。

context.imageSmoothingEnabled = false;

工作完美。 但在我的情況下,更改畫布的大小將此屬性重置為 true。

window.addEventListener('resize', function(e){
    context.imageSmoothingEnabled = false;
}, false)

以下代碼對我有用:

 img.onload = function () { canvas.width = img.width; canvas.height = img.height; context.drawImage(img, 0, 0, img.width, img.height, 0, 0, img.width, img.height); }; img.src = e.target.result; // your src

簡單提示:在 x 和 y 位置用 0.5 繪制。 像 drawImage(, 0.5, 0.5) :D 你會得到清晰的邊緣 :D

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM