ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

C#コミュのBitmapクラスで大きな画像を読む際のエラー

  • mixiチェック
  • このエントリーをはてなブックマークに追加
初めて質問させていただきます。

10800x10800のTIFF画像をBitmapクラスで読み込みたいのですが、エラーが表示されてしまいます。

・開発環境
VisualStudio2003

・実行環境
様々なマシンで試しました。
OS:WindowsXP SP2
Memory:512MBのものから4GBのものまで

・内容
Bitmap img = new Bitmap(fileName);

・エラー内容(2種)
メモリ不足です
パラメーターが違います

8000x8000あたりまでは問題ないのですが。
メモリが不足とでますが、タスクマネージャーではほとんどメモリを使用せずにダイアログが表示されてしまいます。

Bitmapクラスの代わりにFreeImageというグラフィックライブラリを使用してみたのですが、ダイアログは出ないのですが、
大きな画像は読むことができませんでした。

もし何か情報がありましたら宜しくお願いいたします。

コメント(11)

画像全体を一度にロードしなければならない状況なのでしょうか?
部分毎にロードして利用することは考えられませんか?
それか、別に解像度を落としたサムネイル画像を用意するとかかなぁ?

うーん。
何を実現させようとしてますか?
画像を表示させる?それとも画像処理だけですか?
>巨匠さん
書き込みありがとうございます。

本来の目的は、巨大な画像が縦横格子状に並べてあり、それらをより小さいサイズで再度格子状に切り出していくのが目的です。

一枚の画像で例えると、1000x1000の画像を300x300で切り分けて行くような感じです。(隣接画像とまたがる部分の処理は割愛します。)

現状の処理では
・切り出す大きさのBitmapクラスAを用意
・上記のクラスを元にgraphicクラスを作成
・元となる(大きな)画像をBitmapクラスBに読み込み
・graphicクラスにDrawImageメソッドでBitmapクラスBの一部を書き込み
・BitmapクラスAを保存

という手順をとりました。

ある程度のサイズは平気でしたが10000ピクセルを越える辺りでエラーが起きました。

その後Bitmapクラスで読み込むだけのテストプログラムを作り検証したところ同じ症状でした。

上記テストの後だったので問題点のピックアップのみを記述し、本来の目的を記述し忘れました。

巨匠さんのおっゃられている画像の一部のみを読み込む方法があればその方が目的としてはピッタリです。Bitmapクラスのコンストラクタにそれらしき物を見付けられなかったと記憶しているのですが、再度帰宅したら確認してみます。

>タスクマネージャーではほとんどメモリを使用せずに
巨大なメモリを一度に確保しようとしてメモリ失敗した場合、普通にNULLを返してくるので、タスクマネージャで消費メモリが変わらないのはそのせいではないでしょうか?
>一枚の画像で例えると、1000x1000の画像を300x300で切り分けて行くような感じです

本来の目的である1枚の画像を切り分けて描画するという事ですが

一旦イメージを読み込み
#10000*10000ピクサイズを読み込む事は試していませんが・・・。

読み込んだImgをRectAngleで指定した部分だけを
描画すればいいのではないでしょうか。

Image img = Bitmap.FromFile("filename");
Graphics G = e.Graphics;

Rectangle RAngle = new Rectangle(x, y, DrawWidth, DrawHeigh);
G.DrawImage(img, RAngle);

意図した物と違うかもしれませんが
こんな感じで1枚の絵から指定した場所とサイズを指定して
描画は出来そうですがどうでしょうか。

#大分はしょっててすいません・・・。
書き込みありがとうございます。

補足説明ばかりですみません。作業としては分割処理はおこないますがウィンドウ等への画像の表示はしていません。

>スベランカーさん
コードとしてはスペランカーさんに記述頂いた方法とほぼ同様のことをしています。ですが、BitmapクラスやFromImageメソッドの像読み込みの時点でエラーになってしまいます。

>あろTAKE!さん
作成出来ない、または、表示できないということでしょうか?photoshopでは作れていました。mspaintで試してみます。

>巨匠さん
画像の一部を読み込むBitmapクラスのコンストラクタはみつかりませんでした。

残念ながらSystem.Drawing.Bitmapの想定している範囲内の利用から外れてしまっているのではないでしょうか?

Cで書かれていますが、tiffを読むライブラリならこんなのがありました。
http://www.remotesensing.org/libtiff/
画像表示しないならば、.NET以外のライブラリを使う手がありますよね。

Nakaさんが紹介しているLibTiffもいいですね。
あと、LibTiffをラッピングしている、GDALを使ったことありますけど結構よかったですよ。
http://www.remotesensing.org/gdal/
すいません、日が開いてしまいました。
せこさん、あろTAKE!さん、Nakaさん、巨匠さん、情報ありがとうございます。

何故か突然テストだけは通るようになってしまいました。
ですが、自分のプログラムの方ではエラーが出るのでもう一度見直してみます。
プログラムが得意ではないので色々勉強しつつ、ご紹介いただいたライブラリ
も試せればと思ってます。といいつつも少し時間が取れなくなってしまったので
また時間を見つけて試してみて、何かフィードバックできればと思ってます。

特に役に立つ情報ではないのですが、以下は今まで調べた結果です。

■テスト内容
Bitmap bmp = new Bitmap(textBox1.Text);
MessageBox.Show("読み込めました");

解像度 10800x10800(PhotoshopCSにて作成)
JPEG(低圧縮) 61MB
TIFF(LZW圧縮) 100MB
TIFF(非圧縮) 341MB
BMP (非圧縮) 341MB

以前は全てダメだったのですが、何故か読めるようなってしまいました。
特に以前のテスト時と変わったところはないのですが・・・。
因みに15000x15000のjpegを試したところ、以前同様読み込めませんでした。

また、mspaintで10800x10800を試したところ、キャンパスサイズは広げ
られたのですが、保存はリソース不足のエラーが出ました。
Photoshopで作成した10800のbmpは「Windows画像とFAXビューアー」では
「プレビューを利用できませんでした。」という表示となりました。

やはりWindows的には大きすぎるのかもしれません。

オンラインのMSDNに以下の記述などがありました。

----------
GDI+ デコーダには制約があるので、65,535 ピクセルよりも大きい 1 次元の .png イメージ ファイルからビットマップを作成した場合、System.ArgumentException がスローされます。

http://msdn2.microsoft.com/ja-JP/library/3135s427.aspx
----------

また別の関数ですが、

----------
サイズの大きなビットマップでは ArgumentException がスローされる場合があります。最大許容サイズは、コンピュータによって異なります。

http://msdn2.microsoft.com/ja-JP/library/system.windows.forms.control.drawtobitmap.aspx
----------

などの表記もありました。
また、DrawImageなどで使用されるWin32APIのbitblt関数の制限ではという意見もありました。下記はその情報に関するページではありませんが、APIとの対応に関する情報ということで、もし誰かの参考になればと一応記載してみます。

----------
Microsoft Win32 と Microsoft .NET Framework API との対応
http://www.microsoft.com/japan/msdn/net/general/win32map.aspx
----------

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

C# 更新情報

C#のメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング