【问题标题】:Blurry effect using canvas使用画布的模糊效果
【发布时间】:2021-03-08 20:49:07
【问题描述】:

简介

我正在根据以下内容创建一个包含“行”信息的页面:

  • 每一行都包含一个画布
  • 所有行的宽度必须相同:画布最宽的宽度
  • 如果最宽的画布的宽度小于视口,则使用视口的宽度。

解决方案很简单:使用表格(单列)和样式min-width: 100%;。这不是问题。

问题

在画布中绘制的所有内容都有模糊效果。

它(显然)仅发生在(最新版本的)Chrome 中。

重现性

为了重现问题,我创建了this fiddle

在示例中,我创建了两行,每行具有不同的背景颜色,第一个画布呈现文本,第二个画布呈现图形内容。对于图形内容,我使用的是以下图片:

请注意,图像仅包含两种颜色:纯红色和纯绿色。它的大小是 100x100。在第二个画布中,图像显示 10 次,一个并排显示,因此画布宽度为 1000x100。

我正在测试的计算机是 Linux,使用 Chrome 87.0.4280.66 (2020-11-17),这是撰写此问题时的最新稳定版本。

我在其他电脑和浏览器上测试过,结果如下:

  • 同一台 Linux 计算机,(旧)Chrome:好的
  • 同一台 Linux 计算机,Mozilla:好的
  • 另一台 Linux 计算机,(最近的)Chrome:问题
  • 另一台 Linux 计算机,Mozilla:好的
  • MacBook,(最近的)Chrome:问题
  • MacBook、Mozilla:好的
  • MacBook、Safari。好的
  • Android 平板电脑,(旧)Chrome:好的

如果您看到一切正常并且想知道问题的外观,这里是一个屏幕截图。 (可能需要点击100%才能看到,调整大小很难看到问题):

注意:

  • 图像看起来很模糊,混合了红色和绿色(形成栗色)。 5号左右特别臭名昭著。图片。
  • 该问题还会影响文本。如果你仔细看,5号上面的文字。方形比开始时稍微分散一些。

效果类似于在图像中(或在屏幕外画布中)绘制,然后使用不同的比例因子在画布中绘制其内容(即在 99x99 空间中绘制 100x100 图像)所获得的效果),因为效果类似于重采样的典型结果。

我试过了,没有成功

  1. 绘图前context.resetTransform()
  2. context.imageSmoothingEnabled = false。即使它有效,它也解决了图像的问题,但没有解决文本的问题。
  3. context.drawImage()dWidthdHeight 参数,以强制绘制 100x100 目标。
  4. #canvas { image-rendering: pixelated; }
  5. Chrome -> 设置 -> 外观 -> 在可用时使用硬件加速 ->(禁用)
  6. 使用其他方法进行布局。我尝试过使用 DIV 而不是表格。
  7. <canvas>: The Graphics Canvas element

使用 CSS 与 HTML 调整画布大小

可以使用 CSS 更改画布的显示大小,但如果您这样做,图像会在渲染过程中缩放以适应样式大小,这可能会使最终的图形渲染失真。

最好通过直接在元素上设置宽度和高度属性来指定画布尺寸,直接在 HTML 中或使用 JavaScript。

所有画布的东西都是由 Javascript 完成的,没有 CSS,没有 HTML。


你以前有没有尝试过这种效果?你解决了吗?怎么样?

有什么解决办法吗?

如果您试验他的问题,并且您的浏览器与 Chrome 不同,请发表评论,以排除 Chrome 特有的问题。

我们将不胜感激。

【问题讨论】:

  • 考虑 (0,0) 索引第一个像素的左上角这一事实。从此处绘制的垂直 1 像素宽的线将仅对像素的前 1/2 提供全强度。绘制 1 像素宽的线条时,如果将 (0.5,0.5) 视为像素的中心,则会得到更清晰的结果。你实际上几乎在那里。在小提琴中,取消注释 context.imageSmoothingEnabled = false; 并将 0.5 添加到 X 和 Y 坐标。等等 - 图像的未修改副本。 :)
  • 感谢@enhzflep 的评论。不幸的是,它使所有 10 张图像看起来都相同,但这些副本与原始图像完全不同。问候
  • console.log( devicePixelRatio ) 输出什么? this fiddle 的渲染效果更好吗:奇怪的是,您在其他浏览器上还可以……您的浏览器可以应用一些缩放吗?
  • 嗨@Kaiido。 devicePixelRatio 报告了一个奇怪的值 1.001312255859375。我已经验证没有使用缩放。你的小提琴看起来很完美!!!,我不知道devicePixelRatio 的存在。我会立即在我的页面中尝试。非常感谢
  • 嗨@Kaiido,你的解决方案就像一个魅力。我建议您将其写下来作为答案,以便我将其评为正确答案。问候

标签: javascript google-chrome canvas


【解决方案1】:

解决方案要求(如@Kaiido 所述),使用Window.devicePixelRatio

Window 接口的 devicePixelRatio 返回当前显示设备的物理像素分辨率与 CSS 像素分辨率的比率。该值也可以解释为像素大小的比率:一个 CSS 像素的大小与一个物理像素的大小。简单来说,这告诉浏览器应该使用多少屏幕的实际像素来绘制单个 CSS 像素。

解决问题的代码是:

if (devicePixelRatio != 1.0) {
    context.canvas.style.width = (context.canvas.width / devicePixelRatio) + "px";
    context.canvas.style.height = (context.canvas.height / devicePixelRatio) + "px";
}

这也适用于 Chrome 以外的浏览器,它们(在我自己的情况下)为 Window.devicePixelRatio 返回值 1,保持之前的功能不变。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-07
    • 2013-12-04
    • 2021-02-19
    • 1970-01-01
    相关资源
    最近更新 更多