NOTE:これは、既存のキャンバス要素がスケールアップ時にレンダリングされる方法と関係しています。 、notは、線またはグラフィックスのレンダリング方法に関係しますキャンバス表面上。つまり、これはinterpolation of scaled elementsと関係があり、キャンバスに描画されるグラフィックスのantialiasingとは関係ありません。ブラウザがどのように線を引くかは気にしません。ブラウザがキャンバス要素をどのようにレンダリングするかを気にしていますitself拡大されたとき。
<canvas>
要素のスケーリング時に補間を無効にするためにプログラムで変更できるキャンバスプロパティまたはブラウザ設定はありますか?クロスブラウザソリューションは理想的ですが、必須ではありません。 Webkitベースのブラウザーが私の主なターゲットです。パフォーマンスは非常に重要です。
この質問 は最も似ていますが、問題を十分に説明していません。それが価値があるものとして、私はimage-rendering: -webkit-optimize-contrast
を試してみましたが無駄になりました。
アプリケーションは、必要なものを明確にするために、HTML5 + JSで記述された「レトロな」8ビットスタイルのゲームになります。
説明のために、ここに例を示します。 ( ライブバージョン )
21x21のキャンバスがあるとします...
<canvas id='b' width='21' height='21'></canvas>
...要素を5倍(105x105)にするCSSがあります:
canvas { border: 5px solid #ddd; }
canvas#b { width: 105px; height: 105px; } /* 5 * 21 = 105 */
次のように、キャンバスに単純な「X」を描画します。
$('canvas').each(function () {
var ctx = this.getContext("2d");
ctx.moveTo(0,0);
ctx.lineTo(21,21);
ctx.moveTo(0,21);
ctx.lineTo(21,0);
ctx.stroke();
});
左側の画像は、Chromium(14.0)がレンダリングするものです。右側の画像は、私が望むものです(説明のために手描き)。
要素をスケーリングするときに補間を無効にするためにプログラムで変更できるキャンバスプロパティまたはブラウザ設定はありますか?
答えは多分いつかです。今のところ、あなたが望むものを手に入れるには、ハックアラウンドに頼らなければなりません。
image-rendering
CSS3のワーキングドラフトでは、新しいプロパティの概要を説明していますimage-rendering
Image-renderingプロパティは、ユーザーエージェントが適切なスケーリングアルゴリズムを選択するのを支援するために、画像のスケーリング時に画像のどの側面が最も重要であるかについてユーザーエージェントにヒントを提供します。
仕様では、auto
、crisp-edges
、およびpixelated
の3つの許容値の概要を説明しています。
pixelated:
画像を拡大する場合、「最近傍」または同様のアルゴリズムを使用する必要があります。そのため、画像は単純に非常に大きなピクセルで構成されているように見えます。縮小する場合、これは自動と同じです。
これは単なる作業ドラフトであるため、これが標準になるという保証はありません。現在のところ、ブラウザのサポートは最高の状態でしかありません。
Mozilla Developer Networkには、 最新の技術に特化した非常に詳細なページ があります。これを読むことを強くお勧めします。
Webkit開発者は当初 (暫定的に-webkit-optimize-contrast
としてこれを実装する を選択しましたが、Chromium/Chromeはこれを実装するWebkitのバージョンを使用していないようです。
更新:2014-09-12
Chrome 38はimage-rendering: pixelated
をサポートするようになりました !
Firefoxにはimage-rendering: pixelated
を実装するための バグレポート がありますが、現在は-moz-crisp-edges
が機能しています。
したがって、これまでで最もクロスプラットフォームなCSSのみのソリューションは次のとおりです。
canvas {
image-rendering: optimizeSpeed; /* Older versions of FF */
image-rendering: -moz-crisp-edges; /* FF 6.0+ */
image-rendering: -webkit-optimize-contrast; /* Safari */
image-rendering: -o-crisp-edges; /* OS X & Windows Opera (12.02+) */
image-rendering: pixelated; /* Awesome future-browsers */
-ms-interpolation-mode: nearest-neighbor; /* IE */
}
残念ながら、これはまだすべての主要なHTML5プラットフォーム(特にChrome)で動作しません。
もちろん、JavaScriptで高解像度のキャンバスサーフェスに最近傍内挿を使用して画像を手動で拡大することも、画像をサーバー側で事前に拡大することもできますが、私の場合、これは非常にコストがかかるため、実行可能なオプションではありません。
ImpactJS は、テクスチャの事前スケーリング手法を使用して、このFUDをすべて回避します。 Impactの開発者であるDominic Szablewskiは、 これについて非常に詳細な記事を書いた (彼は研究でこの質問を引用することさえしました)。
imageSmoothingEnabled
プロパティに依存するキャンバスベースのソリューションについては、 Simonの答え を参照してください(古いブラウザーでは使用できませんが、事前スケーリングよりも単純で、広くサポートされています)。
canvas
要素に関するMDNの記事で説明されているCSSプロパティをテストしたい場合、ブラウザーに応じて、ぼやけているかどうかにかかわらず、このような表示をする this fiddle を作成しました:
新しい回答7/31/2012
これがついにキャンバス仕様になりました!
仕様では最近imageSmoothingEnabled
と呼ばれるプロパティを追加しました。このプロパティはデフォルトでtrue
に設定され、非整数座標で描画されたイメージまたは描画されたスケーリングがより滑らかなアルゴリズムを使用するかどうかを決定します。 false
に設定されている場合、最近傍が使用され、画像の滑らかさが低下し、代わりにピクセルが大きくなります。
画像の平滑化はごく最近キャンバス仕様に追加され、すべてのブラウザでサポートされているわけではありませんが、一部のブラウザはこのプロパティのベンダー接頭辞バージョンを実装しています。コンテキストには、FirefoxのmozImageSmoothingEnabled
とChromeおよびSafariのwebkitImageSmoothingEnabled
が存在し、これらをfalseに設定すると、アンチエイリアスの発生が停止します。残念ながら、この記事の執筆時点では、IE9およびOperaは、このプロパティ(ベンダープレフィックスなど)を実装していません。
プレビュー:JSFiddle
結果:
2012年7月31日編集-この機能は、現在キャンバス仕様にあります!こちらの別の回答をご覧ください:
https://stackoverflow.com/a/11751817/154112
古い答えは後世のためです。
希望する効果に応じて、これを1つのオプションとして選択できます。
var can = document.getElementById('b');
var ctx = can.getContext('2d');
ctx.scale(5,5);
$('canvas').each(function () {
var ctx = this.getContext("2d");
ctx.moveTo(0,0);
ctx.lineTo(21,21);
ctx.moveTo(0,21);
ctx.lineTo(21,0);
ctx.stroke();
});
これはこれを作成します:
おそらくあなたが望むものではありません。しかし、単にブラーをゼロにしたい場合は、それがチケットになるので、念のために提供します。
より難しいオプションは、ピクセル操作を使用して、ジョブのためにアルゴリズムを自分で記述することです。最初の画像の各ピクセルは、新しい画像の5x5ピクセルのブロックになります。画像データを扱うのはそれほど難しくありません。
ただし、CanvasとCSSだけでは、希望する正確な効果で一方を他方にスケーリングすることはできません。
Google Chromeでは、キャンバスの画像パターンは補間されません。
Namuolの回答 http://jsfiddle.net/pGs4f/ から編集した実際の例を次に示します。
ctx.scale(4, 4);
ctx.fillStyle = ctx.createPattern(image, 'repeat');
ctx.fillRect(0, 0, 64, 64);
Saviskiの回避策 説明 ここ は、以下で動作するため、有望です。
ただし、以下では機能しませんが、CSS画像レンダリングを使用して同じ効果を実現できます。
問題は、ctx.XXXImageSmoothingEnabledが機能せず、画像レンダリングが機能しないためです。