2017-01-13 2 views
0

約9,000 x 9,000ピクセルの画像を表示しようとしています。画像はファイルに保存されます。System.OutOfMemoryExceptionsを取得せずに大きな画像を処理/表示するにはどうすればよいですか?

BitmapImage image = new BitmapImage(new Uri(dialog.FileName)); 

私はそのステートメントの後にイメージをフリーズします。そこから、画像はBitmapSource/BitmapImageとしてプログラムのメソッドに内部的に格納され/渡されます。

私は、MemoryStreamオブジェクト(usingステートメントとすべてに入れたもの)を使用してイメージのサイズ変更/サイズ変更を試みるメソッドを記述しました。たとえば、そのようなメソッドの1つは、次のステートメントから始まります。

 using(MemoryStream stream = new MemoryStream()) 
     { 
      PngBitmapEncoder e = new PngBitmapEncoder(); //BmpBitmapEncoder(); 
      e.Frames.Add(BitmapFrame.Create(image)); 
      e.Save(stream); 
      ... 
     } 

多くの場合、その関数のe.Save(ストリーム)行でSystem.OutOfMemoryException()を取得します。画像のサイズを変更しないと、Imageコントロールを使用して画像を表示するWindowを作成するときにSystem.OutOfMemoryException()が発生します。

   <Image Source="{Binding Image}" HorizontalAlignment="Left" VerticalAlignment="Top" 
       Width="{Binding ImageWidth}" Height="{Binding ImageHeight}" /> 

さて、私は、彼らが必要ないという点でのOutOfMemory例外があいまいなことができることを理解するには、プログラムがアクセスを持っているRAMの量を使い果たしたことを意味します。場合によっては、プログラムがイメージを表示することがあります(OutOfMemoryExceptionがスローされた直後でも)ので、問題のファイルが破損しているとは思われません。フォーマットが無効です。

WPF/.NETで大きな画像ファイルを扱うより良い方法はありますか?どんな提案も大歓迎です!

編集:画像をフリーズする方法を変更しました(元画像をフリーズする代わりにフリーズコピーを作成していました)。

+0

プログラムに「32ビット優先」が選択されていないことを確認してください。プールの断片化のためにOOMを取得している場合は、それが役に立ちます。また、画像のコピーがどこにも漏れていないことを確認してください。 –

+0

私はいくつかのメモリプロファイリングを行っており、プロファイリングの結果は断片化が起こっていることを示唆していません。 また、私のプログラムが32ビットマシン上で機能する必要があるため、64ビットマシンではなく32ビットマシンで動作するソリューションがあれば、残念ながら十分ではありません。選択肢はありますか? – Scusemua

+0

元のイメージをフリーズする代わりにフリーズコピーを作成するのはなぜですか? – Clemens

答えて

0

実際に画像を表示するために完全な解像度が必要ない場合は、BitmapImageのDecodePixelWidthまたはDecodePixelHeightを設定するだけです。画像のアスペクト比を維持するために、両方を設定しないでください。

var image = new BitmapImage(); 
image.BeginInit(); 
image.DecodePixelWidth = 900; 
image.UriSource = new Uri(dialog.FileName); 
image.EndInit(); 
image.Freeze(); 
関連する問題