私は仕事でセンサカメラなどを用いる事があるのですが、ラインセンサは横の画素数が8K(8192画素)ぐらいは、割と普通に使われ、1枚の画像として、縦方向の画素数はいくらでも指定できてしまうため、C#プログラムでBitmapクラスはどの程度の大きさ(画素数)まで対応可能なのか?調べてみました。
評価環境
OS:Windows10 Pro 64bit
Visual Studio Community 2015
.NET Framework 4.6.2
実装メモリ:32GB
評価プログラム実行時の使用メモリ量:約9GB(残23GB)
評価プログラム
private void button1_Click(object sender, EventArgs e)
{
int width = (int)nudWidth.Value;
int height = (int)nudHeight.Value;
// 使用メモリ容量(24bitカラーのとき)
int size = width * height * 3 / 1024 / 1024;
try
{
using (var bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb))
{
MessageBox.Show(size.ToString("#,0") + "MB 確保");
}
} catch
{
MessageBox.Show(size.ToString("#,0") + "MB エラー");
}
}
(実行画面)
評価方法
プラットフォームを Any CPU(32bit優先)、Any CPU(32bit優先なし)、x64で切り替えて、エラーが出るまでHeightの値を大きくしてみました。
32bit優先のあるなしは、プロジェクトのプロパティから、ビルドを選択して 32ビットを優先 の部分のチェックのあるなしで切り替えます。
Bitmapクラスは以下のように24ビットカラーで確保したので、メモリ的には
Width x Height x 3 バイト
確保されます。
var bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb)
結果
プラットフォーム | 最大メモリサイズ |
Any CPU
(32bit優先) |
1GB |
Any CPU
(32bit優先なし) |
2GB |
x64 | 2GB |
ということで、Bitmapクラスで確保できる最大のサイズ(メモリ容量)は 2GB のようです。
プロセス的な限界かないか?と思い、下のようにBitmapクラスを2つ確保してみましたが、結果は同じ(bmp1,bmp2とも2GB分、計4GB確保できる)でした。
private void button1_Click(object sender, EventArgs e)
{
int width = (int)nudWidth.Value;
int height = (int)nudHeight.Value;
// 使用メモリ容量(24bitカラーのとき)
int size = width * height * 3 / 1024 / 1024;
try
{
using (var bmp1 = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb))
using (var bmp2 = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb))
{
MessageBox.Show(size.ToString("#,0") + "MB 確保");
}
} catch
{
MessageBox.Show(size.ToString("#,0") + "MB エラー");
}
}
もともと、なぜエラーになるか?
と思ったのですが、エラーが出たときの画面にヒントがあるような。。
-2,047MB エラー
と表示されいます。
これはメモリのサイズを
int size = width * height * 3 / 1024 / 1024;
と計算していますが、エラーが出るときは
width * height * 3
の値がintの最大値を超えてオバーフローしているためだと思いますが、おそらくBitmapクラス内部でも同じ用なコードがあるのでは?ないでしょうかね。
←画像処理のためのC#テクニックへ戻る
コメント