【问题标题】:Jaggies text when fillText in canvas in chrome在 chrome 中的画布中填充文本时出现锯齿状文本
【发布时间】:2014-04-13 08:26:13
【问题描述】:

我正在尝试在画布中绘制文本,但绘制的文本有锯齿,尤其是在 chrome 31.0.1650 中。 我试过-webkit-font-smoothing:antialiased,text-shadow,但一切都是徒劳的。

如何解决这个问题? 提前致谢。

这里是样式代码:

<style>
    #my_canvas{           
        -webkit-font-smoothing: antialiased;
        text-shadow: 1px 1px 1px rgba(0,0,0,0.004);
        text-indent: -9999px; 
    }                   
</style>

正文中的代码:

<canvas id="my_canvas" height="300" width="2200"></canvas>
<script>
    var canvas = document.getElementById("my_canvas");
    var context = canvas.getContext("2d");
    context.imageSmoothingEnabled =true;
    context.fillStyle = "BLACK";
    context.font = "bold 100px Arial";
    context.fillText("A quick brown fox jumps over the lazy dOg", 50, 200);
</script>

【问题讨论】:

  • 是的,Text 不是 canvas 的强项。您不显示代码,因此很难具体说明。确保不要双笔划或双填文本。大多数字体看起来填充得更好,但没有描边。
  • 请分享您目前尝试过的代码。
  • 谢谢你们!我添加了到目前为止完成的代码。我什至尝试了阴影和模糊效果,但它没有给出预期的结果。
  • @markE 我没有使用双填充文本或描边。我添加了代码,到目前为止已经完成。代码有什么问题吗?
  • @Ken 我已编辑帖子以分享到目前为止完成的代码。

标签: css html5-canvas font-smoothing


【解决方案1】:

这是 Chrome 文本引擎的问题。

您可以使用一种技术来解决这个问题:

  • 将屏幕外画布设置为屏幕画布大小的两倍
  • 将文本按比例绘制到屏幕外画布上:字体大小和位置
  • 将屏幕外画布绘制到缩小的主画布(本例中为一半)。

Live demo here

差异很细微(正如预期的那样),但提高了质量。这是放大:

旁注:CSS 不会影响画布的内容,只会影响元素。图像平滑默认启用,仅影响 图像,但不影响文本或形状(我们将在此技术中使用它)。

var scale = 2;  // scale everything x2.

var ocanvas = document.createElement('canvas');
var octx = ocanvas.getContext('2d');

ocanvas.width = canvas.width * scale;   // set the size of new canvas
ocanvas.height = canvas.height * scale;

// draw the text to off-screen canvas instead at double sizes
octx.fillStyle = "BLACK";
octx.font = "bold " + (100 * scale) + "px Arial";
octx.fillText("A quick brown fox jumps over the lazy dOg", 50*scale, 200*scale);

// key step is to draw the off-screen canvas to main canvas
context.drawImage(ocanvas, 0, 0, canvas.width, canvas.height);

发生的情况是我们在这里在混合中引入了插值。 Chrome 也会将文本非常粗糙地绘制到屏幕外的画布上,但是在文本被光栅化后,我们可以将其作为图像处理。

当我们将画布(又名图像)以一半大小绘制到主画布时,插值(子采样)就会启动,并对像素进行低通滤波,从而获得更平滑的外观。

这当然会占用更多内存,但如果结果很重要,现在付出的代价很小。

您可能会注意到除 2 之外的其他值效果不佳。这是因为画布通常使用双线性插值而不是双三次(这将允许我们使用 4)。但我认为 2x 在这种情况下很适合我们。

为什么不使用转换,即。 scale() ? Chrome 的文本引擎(或它的使用方式)不会将文本光栅化为 1x,然后对其进行转换。它采用向量,对其进行转换,然后对文本进行光栅化,得到相同的结果(即缩放 0.5,绘制双倍)。

【讨论】:

  • 感谢您的帮助。
猜你喜欢
  • 2015-05-02
  • 2013-03-26
  • 2012-06-18
  • 1970-01-01
  • 2011-11-09
  • 1970-01-01
  • 2012-05-02
  • 2013-07-25
  • 1970-01-01
相关资源
最近更新 更多