画布:调整图像大小而不模糊

时间:2018-04-22 15:43:35

标签: javascript html css canvas

我正在尝试在画布中表示图像,并希望画布是其父容器宽度的某个百分比。问题是我在将图像添加到画布时会以某种方式模糊图像,我不想模糊图像。

我认为添加ctx.imageSmoothingEnabled = false会禁用模糊,但似乎并没有帮助。

有谁知道如何防止下面的图像在这个画布中模糊?任何想法都将不胜感激!

var img = new Image();
img.src = 'https://gist.githubusercontent.com/duhaime/019f2ccb98391adbf460a10463059683/raw/c4c2bc1fa923d905aba0ef88e05c0760823d2cca/000630070000650.jpg';

img.onload = function() { 
  var canvas = document.querySelector('canvas');
  canvas.width = hidden.clientWidth;
  canvas.height = hidden.clientHeight;
  var ctx = canvas.getContext('2d');
  ctx.webkitImageSmoothingEnabled = false;
  ctx.mozImageSmoothingEnabled = false;
  ctx.imageSmoothingEnabled = false;
  ctx.drawImage(hidden,
    0, 0, this.naturalWidth, this.naturalHeight,
    0, 0, hidden.clientWidth, hidden.clientHeight)

}
#container {
  width: 800px;
  background: #efefef;
}

#hidden {
  position: absolute;
  top: -1000%;
}

#hidden,
#canvas {
  width: 60%;
}
<div id='container'>
  <img src='https://gist.githubusercontent.com/duhaime/019f2ccb98391adbf460a10463059683/raw/c4c2bc1fa923d905aba0ef88e05c0760823d2cca/000630070000650.jpg' id='hidden'>
  <canvas></canvas>
</div>

2 个答案:

答案 0 :(得分:1)

画布分辨率和显示尺寸不相同。

观察图像,我看到它的尺寸为444像素×800像素,分辨率非常低。它的显示方式在很大程度上取决于显示设备。

您的问题是,将画布显示宽度设置为容器大小的60%以及您为图像设置的画布分辨率(444by800)。

显示宽度和画布分辨率很可能不匹配。

画布显示大小

  • canvas.style.widthcanvas.style.height表示图片将填充的页面区域,与画布分辨率无关。

画布分辨率

  • canvas.widthcanvas.height属性表示画布的分辨率(以像素为单位),用于存储图像内容的实际像素数

浏览器正在添加模糊。

假设60%(对于#hidden {width : 60%})的高清显示宽度为1920px,则画布将延伸超过60% * 1920 = 1152px,这比画布大2.6倍。

画布内容不模糊,您已正确绘制图像。浏览器将画布渲染到页面上的尺寸大于添加模糊的画布分辨率。

简单修复

要阻止浏览器模糊画布的内容,请使用CSS属性image-rendering: pixelated;,如下例所示。

var img = new Image();
img.src = 'https://gist.githubusercontent.com/duhaime/019f2ccb98391adbf460a10463059683/raw/c4c2bc1fa923d905aba0ef88e05c0760823d2cca/000630070000650.jpg';

img.onload = function() { 
  canvas.width = this.naturalWidth
  canvas.height = this.naturalHeight
  var ctx = canvas.getContext('2d');
  // ctx.imageSmoothingEnabled = false;  // not needed as you are not streaching the image
  ctx.drawImage(this, 0, 0);

}
.big {
  width:100%;
  image-rendering: pixelated;
}
<canvas class="big" id="canvas"></canvas>

简单锐化双音B / W.

图像的分辨率非常低,因此在大多数情况下,您无法提高质量。

但是因为它是双音黑&amp;白色(不是黑色,灰色和白色)可以在较大的画布上拉伸并增加对比度,以消除渲染到画布时引入的一些模糊。

通过使用屏幕和颜色刻录复合操作将画布多次渲染到自身顶部。对比度增加以减少模糊但保持较少的像素化外观。

突出显示差异仅使用此方法锐化图像的左半部分。

var img = new Image();
img.src = 'https://gist.githubusercontent.com/duhaime/019f2ccb98391adbf460a10463059683/raw/c4c2bc1fa923d905aba0ef88e05c0760823d2cca/000630070000650.jpg';

img.onload = function() { 
  const bounds = canvas.getBoundingClientRect(); //Get the canvas display sise
  
  canvas.width = bounds.width;
  canvas.height = this.naturalHeight * (bounds.width / this.naturalWidth);
  var ctx = canvas.getContext('2d');
  // draw to canvas 
  ctx.drawImage(this, 0, 0,canvas.width,canvas.height);
  // draw again using screen to up white areas
  ctx.globalCompositeOperation = "screen";
  ctx.drawImage(canvas, 0, 0,canvas.width/ 2,canvas.height,0, 0,canvas.width/ 2,canvas.height);
  // draw again to pukl grays down some 
  ctx.globalCompositeOperation = "color-burn";
  ctx.drawImage(canvas, 0, 0,canvas.width/ 2,canvas.height,0, 0,canvas.width/ 2,canvas.height);
  // draw again using screen to up white areas
  ctx.globalCompositeOperation = "screen";
  ctx.globalAlpha = 0.5;
  ctx.drawImage(canvas, 0, 0,canvas.width/ 2,canvas.height,0, 0,canvas.width/ 2,canvas.height);
  // draw again to pukl grays down some 
  ctx.globalAlpha = 1;
  ctx.globalCompositeOperation = "color-burn";
  ctx.drawImage(canvas, 0, 0,canvas.width/ 2,canvas.height,0, 0,canvas.width/ 2,canvas.height);
  
}
.big {
  width:100%;
}
<canvas class="big" id="canvas"></canvas>

答案 1 :(得分:0)

我不确定这是你需要的,但我对顶部感到惊讶:-1000%。例如,如果在这种情况下,容器给出“position:relative”,则具有%的子项的属性将相对于父项。

var img = new Image();
img.src = 'https://gist.githubusercontent.com/duhaime/019f2ccb98391adbf460a10463059683/raw/c4c2bc1fa923d905aba0ef88e05c0760823d2cca/000630070000650.jpg';

img.onload = function() { 
  var canvas = document.querySelector('canvas');
  canvas.width = hidden.clientWidth;
  canvas.height = hidden.clientHeight;
  var ctx = canvas.getContext('2d');
  ctx.webkitImageSmoothingEnabled = false;
  ctx.mozImageSmoothingEnabled = false;
  ctx.imageSmoothingEnabled = false;
  ctx.drawImage(hidden,
    0, 0, this.naturalWidth, this.naturalHeight,
    0, 0, hidden.clientWidth, hidden.clientHeight)

}
 

#container {
  width: 800px;
  background: #efefef;
  position:relative;
}

#hidden {
  position: absolute;
  top: 0;
  right: 0;
}
#hidden, canvas {
  width: 50%;
}
<div id='container'>
  <img src='https://gist.githubusercontent.com/duhaime/019f2ccb98391adbf460a10463059683/raw/c4c2bc1fa923d905aba0ef88e05c0760823d2cca/000630070000650.jpg' id='hidden'>
  <canvas></canvas>
</div>