1. ホーム
  2. javascript

[解決済み] <canvas> を拡大縮小する際に補間を無効にする

2022-05-30 07:05:44

質問

注意 : これは、どのように 既存の canvas 要素が拡大されたときにレンダリングされる方法と関係があります。 , ではなく 線や図形がどのように描画されるかに関係するものです。 キャンバスの表面に . 言い換えれば、これはすべて 補間 スケールされた要素 とは何の関係もなく アンチエイリアシング とは無関係です。ブラウザがどのように線を描くかには関心がなく、ブラウザがどのように canvas 要素 それ自体 をどのように表示するかです。


拡大縮小時に補間を無効にするために、プログラムで変更できる canvas のプロパティまたはブラウザの設定はありますか? <canvas> 要素を拡大縮小する際に補間を無効にするようなプログラムによる変更は可能ですか? Webkit ベースのブラウザを主なターゲットとしているので、クロスブラウザ ソリューションが理想的ですが、必須ではありません。パフォーマンスは非常に重要です。

この質問 は最も似ていますが、問題を十分に説明していません。参考までに、私が試したのは image-rendering: -webkit-optimize-contrast を試してみましたが、無駄でした。

アプリケーションは、私が何を必要としているかを明確にするために、HTML5+JSで書かれたquot;retro" 8-bit スタイルのゲームになります。


説明のために、以下に例を示します。( ライブ版 )

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) がレンダリングするものです。右の画像は私が欲しいものです (説明のために手描きしました)。

どのように解決するのですか?

最終更新日 2014-09-12

<ブロッククオート

要素を拡大縮小する際に補間を無効にするために、プログラムで変更できる canvas のプロパティまたはブラウザの設定はありますか?

答えは たぶんいつか . 今のところ、欲しいものを手に入れるにはハックアラウンドに頼らざるを得ません。


image-rendering

CSS3 のワーキングドラフトでは、新しいプロパティの概要が示されています。 image-rendering というようにすれば、私が望むことができるはずです。

image-rendering プロパティは、ユーザエージェントが適切なスケーリングアルゴリズムを選択するのを助けるために、画像が拡大縮小されたときに画像のどの側面が最も重要であるかについてのヒントを提供します。

仕様では、受け入れられる 3 つの値の概要を示しています。 auto , crisp-edges そして pixelated .

ピクセル化されました。

画像を拡大するとき、画像が単に非常に大きなピクセルで構成されているように見えるように、"nearest neighbor"または同様のアルゴリズムが使用される必要があります。縮小する場合、これは auto と同じです。

標準? クロスブラウザ?

これは単に 作業ドラフト であるため、これが標準になる保証はありません。ブラウザのサポートは現在、せいぜい不安定です。

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 で高解像度のキャンバス表面に最近傍補間を使用して画像を手動で拡大したり、サーバー側で画像を事前に拡大したりすることもできますが、私の場合、これは禁断のコストがかかるので、実行可能な選択肢ではありません。

インパクトJS は、この FUD を回避するためにテクスチャ プリスケーリング テクニックを使用しています。Impact の開発者である Dominic Szablewski は、次のように述べています。 はこのことについて非常に詳細な記事を書いています。 (彼は最終的にこの質問を研究に引用しています)。

参照 サイモンの回答 に依存する canvas ベースのソリューションについては imageSmoothingEnabled プロパティ(古いブラウザでは使用できませんが、プリスケーリングよりも簡単で、かなり広くサポートされています)に依存する canvas ベースのソリューションです。

ライブ デモ

に関する MDN の記事で説明されている CSS プロパティをテストしたい場合は、次のようにします。 canvas 要素について説明されている CSS プロパティをテストしたいのであれば、私は このフィドル のようなものが表示されるはずです。ブラウザによって、ぼやけたり、そうでなかったりします。