【问题标题】:HTML canvas line color is not accurateHTML 画布线条颜色不准确
【发布时间】:2021-11-11 22:43:00
【问题描述】:

谁能解释一下为什么画布不服从颜色选择以及如何修复它以使其绘制为“真实”颜色? 我知道画布使用 0.5 像素坐标,所以我尝试使用 0.5 增量进行绘制,但它仍然使用时髦的颜色绘制(使用 ColorCop 放大并检查每个像素的颜色:

这是一个小sn-p,它应该画蓝线,两条线并排,第三行1像素远,结果只有第一行是真正的蓝色,其他都是紫色或更糟,包括第一条/最后一条第一行像素:

const canvas = document.getElementById("line"),
      ctx = canvas.getContext("2d");

canvas.width = canvas.height = 100;
ctx.strokeStyle = 'blue';
ctx.lineCap = "square";
ctx.imageSmoothingEnabled = false;

ctx.moveTo(10.5, 40.5);
ctx.lineTo(80.5, 40.5);

ctx.moveTo(10.5, 41.5);
ctx.lineTo(80.5, 41.5);

ctx.moveTo(10.5, 43.5);
ctx.lineTo(80.5, 43.5);

ctx.stroke();
<canvas id="line"></canvas>

我的显示器分辨率为 2560x1440,100% 缩放。不使用系统/浏览器/软件或任何类型的缩放/比例。 如果我在 MS Paint 中绘制一个像素,我会在显示器上看到一个像素,没有抗锯齿,没有伪影。

【问题讨论】:

  • 建议的重复主题不相关,实际上该主题中接受的答案使我的情况更糟。我的显示分辨率是 1440p,系统缩放设置为 100%
  • 如果那里的答案使问题变得更糟,那么它是相关的。我们需要更多信息才能为您提供帮助。请在您的问题中直接以edit 的形式包含所有这些信息。也就是说,我们需要在您的操作系统上设置真正的分辨率(不是任何品牌的 NNNp)、您的网络浏览器的缩放级别、devicePixelRatio 输出的值以及您尝试使用除 ColorCop 之外的其他应用程序。跨度>

标签: javascript html5-canvas


【解决方案1】:

这样做,您的画布将显示高分辨率像素

  1. 将画布宽度和高度设置为(所需宽度和高度)* devicePixelRatio * 2

  2. 使用 css 样式属性将其重新分配到您想要的宽度和高度

  3. 缩放上下文 2、2

    默认情况下,画布上的一个单位正好是一个像素。缩放 转换修改了这种行为。例如,比例因子 0.5 的单位大小为 0.5 像素;因此,形状以正常大小的一半绘制。类似地,缩放因子 2.0 会增加单位大小,使一个单位变成两个像素;形状因此以正常大小的两倍绘制。

const width = height = 100
const pixelRatio = window.devicePixelRatio * 2;
const canvas = document.getElementById('line');
canvas.width = width * pixelRatio;
canvas.height = height * pixelRatio;
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
const ctx = canvas.getContext("2d");
ctx.scale(pixelRatio, pixelRatio);

ctx.strokeStyle = 'blue';
ctx.lineCap = "square";

ctx.moveTo(10.5, 40.5);
ctx.lineTo(80.5, 40.5);

ctx.moveTo(10.5, 41.5);
ctx.lineTo(80.5, 41.5);

ctx.moveTo(10.5, 43.5);
ctx.lineTo(80.5, 43.5);

ctx.stroke();
<canvas id="line"></canvas>

【讨论】:

  • 使用 devicePixelRatio 获取实际的像素比。并非所有高显示器的比率都为 2(例如大多数手机没有),并且强制“普通”显示器绘制两倍它们可以显示的像素只是白白扼杀性能。
  • 即使在使用 devicePixelRatio 后,它仍显示模糊像素,这就是为什么我将 devicePixelRatio 乘以 2 以获得更好的结果。 谢谢
  • 您的比例因子必须与您用于设置画布大小的比率相同。
  • @ManojKumar 你的方法适用于我的显示器,谢谢。它通过每条线显示 100% 准确的颜色,没有颜色变化。但它会影响缩放不是 100% 的其他类型的监视器/操作系统吗? (我想这真的没关系,因为这些用户已经没有得到真正的像素到像素的图像表示)
  • 另外,它会减少最大画布限制吗? stackoverflow.com/questions/6081483/…
【解决方案2】:

您可能正在使用高分辨率显示器。 CSS 将缩放您的画布并创建抗锯齿。

要克服这个问题,您可以将画布的大小乘以显示器的像素比,然后使用 CSS 缩小到预期大小:

const canvas = document.getElementById("line"),
      ctx = canvas.getContext("2d"),
      dPR = window.devicePixelRatio;

// multiply by dPR
canvas.width = canvas.height = 100 * dPR;
// downscale through CSS
canvas.style.width = canvas.style.height = "100px";
ctx.scale(dPR, dPR);

ctx.strokeStyle = 'blue';
ctx.lineCap = "square";
ctx.imageSmoothingEnabled = false;

ctx.moveTo(10.5, 40.5);
ctx.lineTo(80.5, 40.5);

ctx.moveTo(10.5, 41.5);
ctx.lineTo(80.5, 41.5);

ctx.moveTo(10.5, 43.5);
ctx.lineTo(80.5, 43.5);

ctx.stroke();
<canvas id="line"></canvas>

【讨论】:

  • 我没有在我的系统上使用任何类型的缩放,它是具有 100% 缩放的 1440p 显示器。因此,关于视网膜显示的建议“已回答重复”与此处无关。而你的例子实际上变得更糟了......i.imgur.com/qM1bq3U.png
  • 您的操作系统分辨率如何?如果您在 Windows 上,可能会在此处应用默认的 150%。
  • 这就是“缩放”...100%
  • “缩放”可以在 CSS 级别(例如 zoom CSS 属性)、浏览器级别(例如 ctrl + [+])或操作系统级别。 devicePixelRatio 在您的控制台中输出什么。您的操作系统使用的实际像素分辨率是多少?是真的2560px × 1440px吗?
猜你喜欢
  • 1970-01-01
  • 2014-05-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-09
相关资源
最近更新 更多