【问题标题】:HTML5 Canvas .translate and .scale causes jagged edges on imagesHTML5 Canvas .translate 和 .scale 导致图像边缘呈锯齿状
【发布时间】:2016-05-10 11:06:43
【问题描述】:

这是一个示例:Codepen。只需单击画布中的任意位置(它将有黑色边框),就会绘制一个紫色的星星。

如您所见,星形边缘呈锯齿状。它是用.translate.scale 绘制的。要证明 .translate.scale 导致锯齿状边缘,请转到第 28 行(在 CodePen JavaScript 部分中)并取消注释。然后注释掉第 27 行。当您单击画布时,绘制的星形没有.translate.scale,但它没有锯齿状边缘。

星星是在 Adob​​e Illustrator 中绘制的,并以 300x300 像素的 PNG 格式导出。

更新: 顺便说一句,我需要使用PNG。没有JPGSVG等。

我该如何解决这个问题?


到目前为止我已经尝试过但没有帮助:

  1. 在 Adob​​e Illustrator 的常规首选项中关闭了抗锯齿
  2. 在 Adob​​e Illustrator 的文档光栅和效果设置中关闭了抗锯齿
  3. 在 Illustrator 的文档光栅和效果设置中使用屏幕 72ppi 而不是 300ppi(默认)
  4. 在星星上画一个描边(边框),使这个描边的不透明度为 0%。我认为只有边界/边缘会出现锯齿状。因此,我认为笔划将是“不可见的”,canvas 只会使 0% 不透明度的笔划呈现锯齿状,因此没有任何东西看起来是锯齿状的。但这也不起作用。
  5. 我尝试过使用这些 CSS 建议的“hacks”:

    canvas { image-rendering: crisp-edges; /* Older versions of FF */ image-rendering: -moz-crisp-edges; /* FF 6.0+ */ image-rendering: -webkit-optimize-contrast; /* Safari */ image-rendering: -o-crisp-edges; /* OS X & Windows Opera (12.02+) */ /*image-rendering: pixelated; // Awesome future-browsers */ image-rendering: optimize-contrast; -ms-interpolation-mode: nearest-neighbor; /*IE*/ }

  6. 我也尝试过使用这个 JavaScript “hack”:

    context.webkitImageSmoothingEnabled = true; context.mozImageSmoothingEnabled = true; context.imageSmoothingEnabled = true; /// future


注意:我已经在 Safari、Firefox 和 Chrome 上本地尝试了 Codepen 中的所有代码,然后将它们全部添加到 Codepen 中。

【问题讨论】:

  • 您正在缩放位图数据。摆脱那些锯齿状边缘没有简单的方法。你能把星星画成矢量而不是使用位图数据吗?
  • 从一个较大的 .png 文件开始,然后按比例缩小以减少失真。顺便说一句,您可以缩放 html5 画布和 svg 路径而不会失真。
  • 我同意markE,对于这个形状使用上下文绘图操作。此外,imagesmoothingenabled 默认为 true,您可能希望将其设置为 false。

标签: javascript html canvas


【解决方案1】:

如果你把星星改成矢量就可以解决问题了。

star_img.src='data:image/svg+xml;utf8,<svg width="300px" height="275px" viewBox="0 0 300 275" xmlns="http://www.w3.org/2000/svg" version="1.1"><polygon fill="#fdff00" stroke="#605a00" stroke-width="15" points="150,25  179,111 269,111 197,165 223,251  150,200 77,251  103,165 31,111 121,111" /></svg>';

http://codepen.io/anon/pen/QyBGMv

【讨论】:

  • 嗨@mkaatman,谢谢。但是 1. 我没有使用 svg 的 bec。我将在 标记(在弹出窗口中)中使用相同的 .src url,我将其定义为具有宽度和高度的样式属性。通过设置宽度和高度,在画布中绘制的变量会缩小得非常小。这只发生在 Safari 中,它只是鲜为人知的 Safari 错误。 2. 我打开你的 CodePen 并没有画任何东西。 3.我之前试过SVG,锯齿状的边缘也在那里。
  • 顺便说一句,html5 画布绘图命令实际上是矢量命令,它们作为伪位图绘制到画布绘图表面(SVG 也是如此:发出矢量并在位图上渲染到屏幕)。因此,您可以像使用 SVG 一样缩放+绘制而几乎没有失真。 ;-)
  • 我已经更新了 codepen。我不知道它是否适用于 safari,但据说如果您在隐藏的 div safari 中预加载 SVG,则可以使用内联 SVG。否则,您需要直接在画布中绘制星星。
  • @junerockwell 你能指出一些关于这个错误的事情吗?要将 svg 绘制到画布上,您需要将 svg 文档的宽度和高度设置为绝对值(不仅在 safari 中)。如果你需要重用它,在一个可见的 img 标签中,那么你可以使用 CSS 来调整它的大小。如果您设置正确的 viewBox,我不明白为什么它会很小。真正需要注意的是它会污染 IE 中的画布
猜你喜欢
  • 2014-05-18
  • 1970-01-01
  • 1970-01-01
  • 2019-04-30
  • 1970-01-01
  • 2011-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多