当画布中的fillText在chrome中时,jaggies文本

时间:2014-03-10 09:46:19

标签: css3 html5-canvas font-smoothing

我正在尝试在画布上绘制文本,但绘制的文本有锯齿,特别是在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>

1 个答案:

答案 0 :(得分:2)

这是Chrome文本引擎的一个问题。

虽然有一种技术可以解决这个问题:

  • 设置一个超出屏幕画布大小的离屏画布
  • 以缩放:字体大小和位置
  • 将文本绘制到离屏画布
  • 将屏幕外画布缩小到缩小的主画布(在这种情况下为一半)。

Live demo here

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

Compare

旁注: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,绘制双倍)。