web-dev-qa-db-ja.com

HTML <canvas>要素でアンチエイリアスをオフにできますか?

私は <canvas> 要素、線の描画など。

対角線がアンチエイリアス処理されていることに気付きました。私がやっていることのジャギーな外観を好む-この機能をオフにする方法はありますか?

75
Blorgbeard

画像には context.imageSmoothingEnabled= false

ただし、線の描画を明示的に制御するものは何もありません。 getImageDataputImageDataを使用して、独自の線( 難しい方法 )を描画する必要がある場合があります。

49
Kornel

ctx.lineTo(10.5, 10.5)のような座標に_1-pixel_行を描画します。ポイント_(10, 10)_に1ピクセルの線を引くことは、その位置のこの_1_ピクセルが_9.5_から_10.5_に到達することを意味します。キャンバス。

1ピクセルの行がたくさんある場合は、描画する実際の座標に_0.5_を常に追加する必要はないという素敵なトリックは、キャンバス全体でctx.translate(0.5, 0.5)することです始まり。

60
allan

Mozilla Firefoxで実行できます。これをコードに追加します。

contextXYZ.mozImageSmoothingEnabled = false;

Operaこれは現在機能のリクエストですが、うまくいけばすぐに追加されるでしょう。

24
francholi

ベクターグラフィックスをアンチエイリアスする必要があります

アンチエイリアスはrequiredで、非整数座標(0.4、0.4)を含むベクトルグラフィックの正しいプロットに使用されます。

整数以外の座標を指定すると、キャンバスには2つのオプションがあります。

  • Antialias-整数座標が非整数座標からどれだけ離れているか(丸め誤差)に関して座標の周りのピクセルをペイントします。
  • Round-非整数座標に丸め関数を適用します(たとえば、1.4は1になります)。

後者の戦略は静的グラフィックスで機能しますが、小さなグラフィックス(半径2の円)では曲線は滑らかな曲線ではなく明確なステップを示します。

本当の問題は、グラフィックスが移動(移動)するときです。1つのピクセルと別のピクセル(1.6 => 2、1.4 => 1)の間のジャンプは、形状の原点が親コンテナに関連してジャンプする(常にシフトする)ことを意味します1ピクセル上下/左)。

いくつかのヒント

ヒント#1:キャンバスをスケーリング(たとえばx)してアンチエイリアスを弱め(または強化)し、逆スケール(1/x)を適用します自分でジオメトリを作成します(キャンバスを使用しません)。

比較(スケーリングなし):

A few rectangles

(キャンバススケール:0.75、手動スケール:1.33):

Same rectangles with softer edges

および(キャンバススケール:1.33、手動スケール:0.75):

Same rectangles with darker edges

ヒント#2:ジャギーな外観が本当に必要な場合は、各図形を(消去せずに)数回描画してみてください。描画するたびに、アンチエイリアスピクセルが暗くなります。

比較してください。一度描画した後:

A few paths

3回描画した後:

Same paths but darker and no visible antialiasing.

9
Izhaki

Bresenhamのラインアルゴリズムなどのカスタムラインアルゴリズムを使用してすべてを描画します。このjavascript実装を確認してください: http://members.chello.at/easyfilter/canvas.html

これは間違いなくあなたの問題を解決すると思います。

8
raRaRa

画像を縮小してキャンバスに描画するときに問題が発生したことを付け加えます。アップスケーリングでは使用していませんでしたが、スムージングを使用していました。

私はこれを使って解決しました:

function setpixelated(context){
    context['imageSmoothingEnabled'] = false;       /* standard */
    context['mozImageSmoothingEnabled'] = false;    /* Firefox */
    context['oImageSmoothingEnabled'] = false;      /* Opera */
    context['webkitImageSmoothingEnabled'] = false; /* Safari */
    context['msImageSmoothingEnabled'] = false;     /* IE */
}

この関数は次のように使用できます。

var canvas = document.getElementById('mycanvas')
setpixelated(canvas.getContext('2d'))

たぶん、これは誰かに役立つでしょう。

6
eri0o
ctx.translate(0.5, 0.5);
ctx.lineWidth = .5;

このコンボを使用して、ニースの1pxの細い線を描画できます。

5
retepaskab

非常に限られたトリックに注意してください。 2色の画像を作成する場合、色#000000の背景に色#010101の任意の図形を描画できます。これが完了したら、imageData.data []の各ピクセルをテストし、0x00ではない値を0xFFに設定できます。

imageData = context2d.getImageData (0, 0, g.width, g.height);
for (i = 0; i != imageData.data.length; i ++) {
    if (imageData.data[i] != 0x00)
        imageData.data[i] = 0xFF;
}
context2d.putImageData (imageData, 0, 0);

結果は、アンチエイリアス処理されていない白黒画像になります。いくつかのアンチエイリアシングが行われるため、これは完全ではありませんが、このアンチエイリアシングは非常に制限され、形状の色は背景の色に非常に似ています。

4
StashOfCode

StashOfCodeの答えに関する2つのメモ:

  1. グレースケールの不透明なキャンバスでのみ機能します(fillRectを白で、次に黒で描画、またはその逆)
  2. 線が細い場合(〜1pxの線幅)に失敗することがあります

代わりにこれを行うことをお勧めします:

ストロークして#FFFFFFで塗りつぶしてから、次の操作を行います。

imageData.data[i] = (imageData.data[i] >> 7) * 0xFF

それは1px幅の線でそれを解決します。

それ以外に、StashOfCodeのソリューションは、独自のラスター化関数を記述する必要がないため、完璧です(ラインだけでなく、ベジェ、円弧、穴のある多角形などを考えてください)

0
Matías Moreno