Jaggies文本时,fillText在画布在chrome [英] Jaggies text when fillText in canvas in chrome

查看:191
本文介绍了Jaggies文本时,fillText在画布在chrome的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在画布上绘制文字,但绘制的文字有锯齿,特别是在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_canvasheight =300width =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(快速棕色狐狸跳过懒惰的dOg,50,200);
< / script>


解决方案

这是Chrome文本引擎的问题。 / p>

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





  • 在缩放比例下将文本绘制到屏幕画布上:字体大小和位置

  • <


在此演示



差异是微妙的(如预期),但改善质量。这是一个放大图:





Sidenotes:CSS不影响画布的内容,只影响元素。默认情况下启用图片平滑,并且仅影响图片,但不会影响文字或形状(我们将使用此技术)。

  var scale = 2; // scale everything x2。 

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

ocanvas.width = canvas.width * scale; //设置新画布的大小
ocanvas.height = canvas.height * scale;

//将文本绘制到屏幕画布上,而不是双倍大小
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);

//关键步骤是将离屏画布绘制到主画布中
context.drawImage(ocanvas,0,0,canvas.width,canvas.height)

会发生什么是我们在混合中引入插值。 Chrome会将文本粗糙也画到屏幕外,但在文本变成光栅化后,我们可以将其作为图像处理。



当我们绘制画布(aka图像)到我们的主画布的一半大小,插值(子采样)踢,将低通滤波像素,使更流畅的外观。



当然会花更多的记忆,但如果结果是重要的是一个很小的价格现在支付。



你可能会注意到,其他值2不工作这么好。这是因为画布通常使用双线性插值,而不是双三次(这将允许我们使用4)。但我认为2x在这种情况下对我们很好。



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


I am trying to draw text in canvas but the drawn text has jaggies especially in chrome 31.0.1650. I have tried -webkit-font-smoothing:antialiased,text-shadow but all go in vain.

How to tackle this problem? Thanks in advance.

Here is the style code:

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

The code in body:

<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>

解决方案

This is an issue with the Chrome text engine.

There is a technique you can use to get around this though:

  • Setup an off-screen canvas double the size of the on-screen canvas
  • Draw the text to the off-screen canvas in scale: font size and position
  • Draw the off-screen canvas to main canvas scaled down (half in this case).

Live demo here

The difference is subtle (as expected) but improves the quality. Here is an enlargement:

Sidenotes: CSS does not affect content of the canvas, only elements. Image smoothing is enabled by default and affects only images but not text or shapes (we will use this though for this technique).

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);

What happens is that we are introducing interpolation in the mix here. Chrome will draw the text very rough also to the off-screen canvas, but after the text becomes rasterized we can deal with it as an image.

When we draw the canvas (aka image) to our main canvas at half the size, interpolation (sub-sampling) kicks in and will low-pass filter the pixels giving a smoother look.

It will of course take more memory but if result is important that is a small price to pay nowadays.

You will probably notice that other values than 2 doesn't work so well. This is because the canvas typically uses bi-linear interpolation rather than bi-cubic (which would allow us to use 4). But I think 2x serves us well in this case.

Why not using transform, ie. scale() ? Chrome's text engine (or the way it's used) does not rasterize the text at 1x and then transforms it. It takes the vectors, transforms them and then rasterize the text which will give the same result (ie. scale 0.5, draw double).

这篇关于Jaggies文本时,fillText在画布在chrome的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆