web-dev-qa-db-ja.com

C#.NETビットマップの最大解像度はどれくらいですか?

理論的には、約17GBの十分なメモリがある場合、65,535 x65,535になります。

ただし、テストするために.NET 4.5コンソールアプリケーションを作成すると、System.ArgumentExceptionがスローされます。パラメータが無効です。

アプリケーションは64ビットプラットフォーム用に構築されています。 32GBのメモリを搭載した64ビットプラットフォームで実行されます。私が得ることができた最大解像度は22,000x22,000ピクセルです。

これに関するドキュメントは見つかりませんでした。

また、奇妙な動作として、22,000 x 22,000ピクセルでも、常に機能するとは限りません。動作することもあれば、例外をスローすることもあります。これは、連続したメモリ割り当てに関連していると思いますが、約30GBの空きメモリがあります。

誰かがこれについて何か経験がありますか?また、たとえば100,000 x 100,000ピクセル以上の画像で作業したい場合、独自のビットマップを実装する以外に最善の方法は何でしょうか。

編集:問題は.NETの最大オブジェクトサイズではありません。これは、64ビットプラットフォームをターゲットにして、アプリケーション構成でgcAllowVeryLargeObjectsフラグを設定することで解決できます。このようにして、アプリケーションに1つの整数配列で15GBを超えるメモリを消費させることができます。これまでのところ、答えはGDI +の基本的な実装にあるようですが、どうすればそれを回避できますか?

12
Seong Yup Yoo

これは、Windowsによって課せられるGDI +の制限です。 GDI +は、ビットマップのピクセルデータのメモリマップトファイルビューを作成します。これにより非常に効率的になり、ビットマップは大きくなる傾向があり、MMFはピクセルデータをページングファイルから除外するのに役立ちます。 RAMページは単純に破棄してファイルから再度読み取ることができます。また、多くのプログラマーは、古いビットマップを破棄するのを忘れたときに、Save()呼び出しが異常な例外で失敗するのを見てきました。 。

Windowsは、MMFのビューの大きさ、つまり、 このMSDNの記事 に記載されているように、直接アドレス指定できるファイル内のデータの量を制限します。

名前付きファイルに基づくファイルマッピングオブジェクトのサイズは、ディスク容量によって制限されます。ファイルビューのサイズは、予約されていない仮想メモリの利用可能な最大の連続ブロックに制限されます。これは、最大2 GBから、プロセスによってすでに予約されている仮想メモリを差し引いたものです。

「利用可能な最大の連続ブロック」は、32ビットプロセスの制限であり、約600 MBをホバリングする傾向があり、ギブまたはテイクします。 2 GBの制限は、64ビットプロセスで始まります。技術的には、GDI +はビューを再マッピングすることで、この制限を回避できます。しかし、そうではありません。LockBits()メソッド(内部でも頻繁に使用されます)は非効率的で、使用するのが非常に厄介です。

より大きなビットマップを使用するには、GDI +の後継であるWIC( Windows Imaging Component )に移動する必要があります。 System.Windows.Media.Imaging名前空間を介して.NETで公開されます。

20
Hans Passant

.net内で許可されている最大オブジェクトサイズに達しています。それはここでカバーされています: 。Netの非常に大きなコレクションはメモリ不足の例外を引き起こします

編集:あなたはGDIPlus。Hans ' answer の制限に直面しているようです。あなたが制限内で生きることができるなら、私の答えはいくつかのガイダンスを提供することができます。

作成できる最大のビットマップを計算できることを知っています。

  • オブジェクトの最大サイズは2GB:2,147,483,648です
  • デフォルトのビットマップは32bpp(4バイト)で、最大の領域は2GB/4 = 536,870,912です。
  • 正方形が必要な場合、取得できる最大値はsqrt(2GB/4)= 23,170です。

したがって、次のコードは正常に機能します。

Bitmap b = new Bitmap(23170,23170);

しかし、以下は失敗します:

Bitmap b = new Bitmap(23171,23170);

より大きなサイズの画像を保存する場合は、ピクセル形式をより少ないbpp数に変更する必要があります。

Bitmap b = new Bitmap(65535,65535, PixelFormat.Format4bppIndexed);
6
John Koerner

ビットマップファイル形式仕様のバイト単位のサイズ制限は2 ^ 32バイトです。
使用する数に応じて、この制限に早く到達しますピクセルあたりのバイト数

1
Mauro Sampietro