javascript - Canvas :调整图像大小而不模糊

标签 javascript html css canvas

我试图在 Canvas 中表示图像,并希望 Canvas 占其父容器宽度的一定百分比。问题是我在将图像添加到 Canvas 时以某种方式模糊了图像,而我不想模糊图像。

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

有谁知道如何防止下面的图像在此 Canvas 中模糊?任何想法将不胜感激!

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>

最佳答案

Canvas 分辨率和显示尺寸不一样。

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

在您的问题中,将 Canvas 显示宽度设置为容器大小的 60%,并将 Canvas 分辨率设置为图像 (444by800)。

很有可能是显示宽度和 Canvas 分辨率不匹配。

Canvas 显示大小

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

Canvas 分辨率

  • canvas.widthcanvas.height 属性代表 Canvas 的像素分辨率,实际用于存储图像内容的像素数

浏览器正在添加模糊。

假设 60%(对于 #hidden {width : 60%})是 1920px 宽的高清显示器, Canvas 将被拉伸(stretch) 60% * 1920 = 1152px 比 Canvas 大 2.6 倍。

Canvas 内容没有模糊,你已经正确地绘制了图像。是浏览器将 Canvas 渲染到页面上,尺寸大于添加模糊的 Canvas 分辨率。

简单修复

要阻止浏览器模糊 Canvas 的内容,请使用 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>

简单锐化双色调黑白。

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

但由于它是黑白两种色调(不是黑色、灰色和白色),您可以在更大的 Canvas 上拉伸(stretch)它并增加对比度以消除渲染到 Canvas 时引入的一些模糊。

它是通过使用屏幕和颜色加深复合操作多次在其自身之上渲染 Canvas 来完成的。增加对比度以减少模糊,同时保持较少像素化的外观。

突出差异使用此方法仅对图像的左半部分进行了锐化。

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>

关于javascript - Canvas :调整图像大小而不模糊,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49967760/

相关文章:

javascript - 无法从 javascript 中的对象获取属性,但可以在记录其父级时将其打印到控制台

javascript - 优化完全相同的 iframe 的加载

html - 从模式页面提交时启用 ionic 导航栏按钮

javascript - 在一定次数的点击后执行操作,例如显示图片

html - 当鼠标悬停在父跨度上时显示跨度元素

css - 背景图片无法缩放以适合网站

javascript - 使用 ajax 填写已选择的参数的表单

javascript - 自定义输入在 jQuery token 输入插件中不起作用

html - 我有一个宽度为 1240px 的 wrapper 和一个中间有 1240px 空白空间的图像。如何放置它以便 wrapper 覆盖它?

javascript - Laravel blade View 相对路径