Javascript HTML5 Canvas.translate和.scale会导致图像上出现锯齿状边缘

Javascript HTML5 Canvas.translate和.scale会导致图像上出现锯齿状边缘,javascript,html,canvas,Javascript,Html,Canvas,这是一个示例:。只需点击画布上的任何地方(它将有黑色边框),就会画出一颗紫色的星星 如你所见,这颗星有锯齿状的边缘。它是用.translate和.scale绘制的。要证明.translate和.scale导致锯齿状边缘,请转到第28行(在CodePen JavaScript部分)并取消注释。然后注释掉第27行。单击画布时,绘制的星形没有.translate和.scale,但没有锯齿状边缘 这颗星是用Adobe Illustrator绘制的,并以300x300px PNG格式导出 更新: 顺便说一

这是一个示例:。只需点击画布上的任何地方(它将有黑色边框),就会画出一颗紫色的星星

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

这颗星是用Adobe Illustrator绘制的,并以300x300px PNG格式导出

更新: 顺便说一下,我需要使用PNG。无
JPG
SVG

如何解决此问题?


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

  • 在Adobe Illustrator的“常规首选项”中关闭抗锯齿
  • 在Adobe Illustrator的文档光栅和效果设置中关闭抗锯齿
  • 在Illustrator的文档光栅和效果设置中使用屏幕72ppi而不是300ppi(默认值)
  • 在星形上放置一个笔划(边框),并使该笔划具有0%的不透明度。我认为只有边界/边缘变得参差不齐。因此,我认为笔划是“不可见的”,即
    canvas
    只会使0%不透明度笔划成为锯齿状,因此没有任何东西看起来是锯齿状的。但这也不起作用
  • 我尝试过使用CSS建议的“黑客”:

    canvas{
    图像渲染:清晰边缘;/*旧版本的FF*/
    图像渲染:-moz清晰边缘;/*FF 6.0+*/
    图像渲染:-webkit优化对比度;/*Safari*/
    图像渲染:-o-crisp-edges;/*OS X和Windows Opera(12.02+)*/
    /*图像渲染:像素化;//非常棒的未来浏览器*/
    图像渲染:优化对比度;
    -ms插值模式:最近邻;/*IE*/
    }

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

    context.webkitmagesmoothingEnabled=true;
    context.mozImageSmoothingEnabled=true;
    context.imageSmoothingEnabled=true;//未来



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

    如果您将星号更改为矢量,则问题将迎刃而解

    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>';
    
    star\u img.src='data:image/svg+xml;utf8';
    

    您正在缩放位图数据。没有简单的方法可以去除那些锯齿状的边缘。你能把星星画成矢量而不是使用位图数据吗?从一个更大的.png开始,先把它缩小,这样它就可以以更少的失真来放大。顺便说一句,您可以在几乎不失真的情况下缩放html5画布和svg路径。另外,ImageSmoothInEnabled默认为true,您可能想将其设置为false。您好@mkaatman,谢谢。但是1。我没有使用svg的bec。我将在标签(在弹出窗口中)中使用相同的.src url,我将其定义为具有宽度和高度的样式属性。通过设置宽度和高度,在画布中绘制的变量将缩小到非常小的比例。这只发生在Safari中,它只是鲜为人知的Safari bug。2.我打开你的密码笔,什么也没画出来。3.我以前尝试过使用
    SVG
    ,锯齿状的边缘也在那里。顺便说一句,html5画布绘制命令实际上是矢量命令,作为伪位图绘制到画布绘制表面(SVG的作用相同:在位图上发出矢量并渲染到屏幕)。因此,您可以像使用SVG一样,以较小的失真进行缩放+绘制。;-)我已经更新了密码笔。我不知道它是否适用于safari,但假设您将SVG预加载到隐藏的div中,safari可以使用内联SVG。否则,您需要直接在画布上绘制星星。@junerockwell您能指出一些关于这个bug的信息吗?要在画布上绘制svg,需要将svg文档“a宽度和高度”设置为绝对值(不仅仅在safari中)。如果您需要在一个可见的img标记中重用它,那么您可以使用CSS来调整它的大小。我不明白,如果设置适当的viewBox,它为什么会很小。真正需要注意的是,它会污染IE中的画布