<canvas>のスケーリング時に補間を無効にする


126

:これはどのように関係しているスケールアップ時に既存のcanvas要素がレンダリングされているいない線やグラフィックスのレンダリング方法を行うにはキャンバスの表面に。つまり、これは、スケーリングされた要素の補間に関するすべてのことであり、キャンバスに描画されるグラフィックのアンチエイリアスとは何の関係もありません。ブラウザがどのように線を引くかについては気にしていません。拡大したときに、ブラウザー要素がキャンバス要素自体をどのようにレンダリングするかを気にします。


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

この質問は最も類似していますが、問題を十分に説明していません。それが価値があるもののために、私はimage-rendering: -webkit-optimize-contrast無駄にしようとしました。

アプリケーションは、必要なものを明確にするためにHTML5 + JSで書かれた「レトロ」な8ビットスタイルのゲームになります。


説明のために、ここに例を示します。(ライブバージョン

21x21のキャンバスがあるとしましょう...

<canvas id='b' width='21' height='21'></canvas>

... CSSがあり、要素を5倍にします(105x105):

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

Chromeはスケーリングされたキャンバス要素を補間します 補間されていないバージョン


1
同一ではないものの、多少、関連:stackoverflow.com/questions/195262/...
HostileForkがdont信頼SE言う

1
この質問は、アンチエイリアスされた線を描く線描画関数に関係していると思います。サイズ変更されたキャンバス要素がデフォルトでどのように補間でレンダリングされるかについて言及しています。
ナムオール2011

はい、申し訳ありません...私は最初に同じことを考え、それからすぐに私の間違いに気付きました。:-/ jsmanipulateのピクセレーションフィルターを使用しようとした場合はどうなりますか? joelb.me/jsmanipulate
HostileForkはSEを信頼してはいけないと言う

1
これは、写真用のイメージフィルターです。
ナムオール2011

はい、ただし、それがあなたの左の画像をあなたの右の画像の十分なバージョンに変換してあなたを幸せにするなら、それはクロスブラウザソリューションを提供することができます、WebKit)。それが実行可能な代替であるかどうかは、解決しようとしている問題に依存します...本当に個別のピクセル描画が必要か、または結果が特定の粒度でピクセル化されていることを確認しようとしているだけなのか。
HostileForkはいけない信頼SE言う

回答:


126

最終更新日:2014年9月12日

要素をスケーリングするときに補間を無効にするようにプログラムで変更できるキャンバスプロパティまたはブラウザ設定はありますか?

答えは多分いつかです。とりあえず、ハックアラウンドに頼って必要なものを入手する必要があります。


image-rendering

CSS3のワーキングドラフトは、新しいプロパティの概要を示していますimage-rendering

image-renderingプロパティは、ユーザーエージェントに適切なスケーリングアルゴリズムの選択を支援するために、画像のスケーリング時に保持する最も重要な画像の側面に関するヒントをユーザーエージェントに提供します。

仕様autoではcrisp-edges、3つの許容値(、、)が概説されていますpixelated

ピクセル化:

画像を拡大するときは、「最も近いもの」または類似のアルゴリズムを使用して、画像が非常に大きなピクセルで単純に構成されているように見えるようにする必要があります。スケールダウンする場合、これは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で高解像度のキャンバスサーフェスに最近傍補間を使用して画像を手動で拡大することも、サーバー側で画像を事前に拡大することもできますが、私の場合、これは非常にコストがかかるため、実行可能なオプションではありません。

ImpactJSは、テクスチャの事前スケーリング技術を使用して、このすべてのFUDを回避します。Impactの開発者であるDominic Szablewskiは、これについて非常に詳細な記事を書いています(彼は研究でこの質問を引用してしまいました)。

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

ライブデモ

あなたがMDNの記事で説明したCSSプロパティをテストしたい場合はcanvas要素を、私が作ったこのフィドルブラウザによっては、ぼやけたりない、このような何かを表示する必要があります。 アイソメトリックピクセルアートスタイルのテレビの4:1(64x64〜256x256)画像


画像レンダリングは他の場所でも機能するようですが、Webkitブラウザーです。Chrome / Chromium / Safariのスタッフが「低負荷状態でEPX補間に切り替える」の意味をよく読んでくれることを本当に望みます。私は最初の文を読んだとき、私はその最適化、コントラストが低負荷で作成した新しいカラーを可能に思ったが、NO:en.wikipedia.org/wiki/...
ティモKähkönen

2
MacおよびWindows上のOpera 12.02は、イメージレンダリング:-o-crisp-edges(jsfiddle.net/VAXrL/21)をサポートしているため、回答に追加できます。
TimoKähkönen2012年

ブラウザのズーム率を上げても機能するはずですか?ブラウザーのズームが150%で、すべてのブラウザーで結果がぼやけている場合、Windows 7でFF 22、Chrome 27、IE 10で描画をテストしました。キャンバスの幅と高さを2倍にしてCSSで元の幅と高さに戻すと、シャープな線が描画されます。
パブロ2013

それは良い質問です。ユーザー指定のスケーリング動作の仕様があるかどうかはわかりません。
namuol 2013

1
私はChrome 78を使用しています(現在の未来からです)。「イメージレンダリング:ピクセル化」が表示されています。ワーキング。2015年にChrome 41に追加されたようです:developer.google.com/web/updates/2015/01/pixelated
MrColes

61

新しい回答7/31/2012

いよいよキャンバス仕様になりました!

この仕様では最近、と呼ばれるプロパティが追加されましたimageSmoothingEnabled。これはデフォルトでtrue、整数以外の座標で描画された画像またはスケーリングされて描画された画像がより滑らかなアルゴリズムを使用するかどうかを決定します。に設定されている場合はfalse、nearest-neighborが使用され、滑らかさの低下した画像が生成され、代わりに見た目の大きいピクセルが作成されます。

画像のスムージングがキャンバス仕様に追加されたのはごく最近であり、すべてのブラウザーでサポートされているわけではありませんが、一部のブラウザーでは、このプロパティのベンダープレフィックスバージョンが実装されています。コンテキストではmozImageSmoothingEnabled、FirefoxとwebkitImageSmoothingEnabledChromeとSafari に存在し、これらをfalseに設定すると、アンチエイリアスが発生しなくなります。残念ながら、執筆時点では、IE9とOperaはこのプロパティを実装していません。


プレビュー:JSFiddle

結果:

ここに画像の説明を入力してください


1
残念ながら、これもまだ機能していないようです。多分私は何かが足りないのですか?これがテストです:jsfiddle.net/VAXrL/187
namuol

12
機能するためには、キャンバスAPIを使用してスケーリングする必要があります。CSSを使用してスケーリングしたり、キャンバスAPIに影響を与えることはできません。したがって、このようなもの:jsfiddle.net/VAXrL/190
Simon Sarris

1
しかし、この問題の本質は、キャンバスに関するものではありません。これは、ブラウザが<canvas>要素を含むスケーリングされた画像をどのようにレンダリングするかについてです。
namuol 2012

4
CSSを使用してスケーリングする場合、namuolのソリューションが機能します。画像をCanvasに手動で拡大縮小すると、Simonのソリューションが機能します。どちらの場合にも解決策があるのは素晴らしいので、両方に感謝します!
ショーンレブロン

IE 11の場合:msImageSmoothingEnabledが機能します!msdn.microsoft.com/en-us/library/dn265062(v=vs.85).aspx
steve

11

編集7/31/2012-この機能は現在キャンバス仕様にあります!ここで別の答えを参照してください:

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

http://jsfiddle.net/wa95p/

これはこれを作成します:

ここに画像の説明を入力してください

おそらくあなたが望むものではありません。ただし、ぼかしをゼロにすることだけを目的としている場合は、それがチケットになるので、念のため提供します。

より難しいオプションは、ピクセル操作を使用して、ジョブ用のアルゴリズムを自分で作成することです。最初の画像の各ピクセルは、新しい画像のピクセルの5x5ブロックになります。画像データを扱うのはそれほど難しくありません。

ただし、CanvasとCSSだけでは、希望どおりの効果で1つをもう1つにスケーリングするのに役立ちません。


ええ、それは私が恐れていたものです。どうやら、image-rendering: -webkit-optimize-contrastトリックを行う必要がありますが、何もしないようです。最近傍内挿を使用してキャンバスのコンテンツを拡大する関数のローリングを検討する場合があります。
namuol 2011

私はもともとあなたの答えを受け入れました。これが重複しているかどうかについて混乱があるように思われるので、私は今のところそれを取り消しました。
namuol

調査を行った結果、より完全な回答が得られました。質問を再度開いて回答を提供したいと思います。
namuol

3

グーグルクロームでは、キャンバス画像パターンは補間されません。

これは、namuolの回答http://jsfiddle.net/pGs4f/から編集された実用的な例です

ctx.scale(4, 4);
ctx.fillStyle = ctx.createPattern(image, 'repeat');
ctx.fillRect(0, 0, 64, 64);

これは、これまでに見た中で最も魅力的な回避策です。パフォーマンスについてはまだわかりませんが、調べる価値は十分あります。やってみます。
namuol

リピートなしの代わりにリピートを使用する方が高速です。理由がわからない。また、これはかなり高速であり、three.jsはCanvasRendererでこれを使用します
saviski

6
更新:Chrome 21で動作しなくなりました(Retinaディスプレイサポートが追加されたため?)新しいバージョンjsfiddle.net/saviski/pGs4f/12は、サイモンが指すimageSmoothingEnabledを使用します
saviski

Retinaの解像度が一般的になると、状況は大きく変わります。iPhone4-5スタイルの326dpi(128dpcm)Retinaディスプレイが24インチ(52x32cm)モニターになると、画面サイズは6656 x 4096 pxになります。その場合、アンチエイリアスは不適切であり、すべてのブラウザーベンダー(Webkitベースであっても)はアンチエイリアスを無効にすることを強制されます。アンチエイリアスはCPUを集中的に使用する操作であり、アンチエイリアス6656 x 4096 pxの画像は遅すぎるでしょうが、そのようなディスプレイでは幸い不必要です。
TimoKähkönen12年

1
余談ですが、これは画像とベンチマークの比較です。jsperf.com/ drawimage
canvaspattern

1

ここで説明されているSaviskiの回避策は有望です。

  • Chrome 22.0.1229.79 Mac OS X 10.6.8
  • Chrome 22.0.1229.79 m Windows 7
  • Chromium 18.0.1025.168(Developer Build 134367 Linux)Ubuntu 11.10
  • Firefox 3.6.25 Windows 7

ただし、以下では機能しませんが、CSS画像レンダリングを使用して同じ効果を得ることができます。

  • Firefox 15.0.1 Mac OS X 10.6.8(image-rendering:-moz-crisp-edges これで動作します
  • Opera 12.02 Mac OS X 10.6.8(image-rendering:-o-crisp-edges works in this
  • Opera 12.02 Windows 7(image-rendering:-o-crisp-edgesはこれで動作します

ctx.XXXImageSmoothingEnabledが機能せず、画像レンダリングが機能しないため、問題は次のとおりです。

  • Safari 5.1.7 Mac OS X 10.6.8。(画像レンダリング:-webkit-optimize-contrastは機能しません)
  • Safari 5.1.7 Windows 7(image-rendering:-webkit-optimize-contrastは機能しません)
  • IE 9 Windows 7(-ms-interpolation-mode:nearest-neighborは機能しません)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.