1

キャンバスにテキストを描画しようとしていますが、特にクロム 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>
4

1 に答える 1

2

これは、Chrome テキスト エンジンの問題です。

ただし、これを回避するために使用できるテクニックがあります。

  • オンスクリーン キャンバスの 2 倍のサイズのオフスクリーン キャンバスをセットアップする
  • オフスクリーン キャンバスにテキストを拡大縮小して描画します: フォント サイズと位置
  • オフスクリーン キャンバスをメイン キャンバスに縮小して描画します (この場合は半分)。

ライブデモはこちら

違いは微妙ですが (予想どおり)、品質が向上します。ここに拡大があります:

比較

補足: 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 以外の値ではうまく機能しないことに気付くでしょう。これは、キャンバスがバイ 3 次補間ではなくバイ 1 次補間を使用するためです (これにより 4 を使用できます)。しかし、この場合は 2x がうまく機能すると思います。

変換を使用しないのはなぜですか。scale()? Chrome のテキスト エンジン (またはその使用方法) は、テキストを 1x でラスタライズしてから変換しません。ベクトルを取得し、それらを変換してからテキストラスタライズしますが、同じ結果が得られます (つまり、スケール 0.5、double を描画)。

于 2014-03-13T07:40:07.590 に答える