HTML5 - Canvas,drawImage()绘制图像模糊

时间:2015-08-10 00:10:14

标签: javascript html5 canvas

我试图将以下图像绘制到画布上,但尽管定义了画布的大小,但它看起来很模糊。正如您在下面看到的那样,图像清晰而清晰,而在画布上,图像模糊且像素化。

enter image description here

以下是它的外观(左边是原始的,右边是绘制的画布,模糊不清。)

enter image description here

我做错了什么?

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>

6 个答案:

答案 0 :(得分:16)

发生这种情况的原因是抗锯齿。 只需将imageSmoothingEnabled设置为假即可

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);
};

答案 1 :(得分:11)

您的问题是canvas{width:512}与画布属性width=521的css约束将使浏览器重新取样整个画布。

要避免它,请删除那些css声明。

&#13;
&#13;
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);
};
&#13;
#canvas {
  background: #ABABAB;
  position: relative;
  z-index: 1;
}
&#13;
<canvas id="canvas" height="352" width="521"></canvas>
&#13;
&#13;
&#13;

另外,如果您要重新采样图像(从32x32到其他尺寸),@ canvas&#39;解决方案将是可行的方法。

答案 2 :(得分:1)

以下代码适用于我:

&#13;
&#13;
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
&#13;
&#13;
&#13;

答案 3 :(得分:1)

除了@canvas回答。

context.imageSmoothingEnabled = false;

完美的作品。但在我的情况下,更改canvas的大小会将此属性重置为true。

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

答案 4 :(得分:1)

当我遇到有关某些问题的旧帖子时,这里还有更多的见解,可以将模糊的图像放置在“ imageSmoothingEnabledEnabled”解决方案之上。

这是专门针对监视器特定渲染的用例,只有某些人试图将视网膜质量的图形渲染到画布中而结果令人失望时,才会遇到此问题。

本质上,高密度显示器意味着您的画布需要容纳额外的像素密度。如果您什么也不做,画布将仅在其上下文中渲染足够的像素信息以说明像素比例为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的pixelRatio监视器上,则画布质量不会出现差异。

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

答案 5 :(得分:-3)

简单提示:在x和y位置使用.5绘制。喜欢drawImage(,0.5,0.5):D你得到清晰的边缘:D