web-dev-qa-db-ja.com

バイト配列をビットマップ画像に変換する

バイト配列をSystem.Windows.Media.Imaging.BitmapImageに変換し、イメージコントロールでBitmapImageを表示します。

最初のコードを使用しているとき、注意が発生します!エラーも画像も表示されません。しかし、2番目のものを使用しているときは正常に動作します!誰が何が起こっているか言うことができますか?

最初のコードは次のとおりです。

public BitmapImage ToImage(byte[] array)
{
   using (System.IO.MemoryStream ms = new System.IO.MemoryStream(array))
   {
       BitmapImage image = new BitmapImage();
       image.BeginInit();
       image.StreamSource = ms;
       image.EndInit();
       return image;
   }
}

2番目のコードは次のとおりです。

public BitmapImage ToImage(byte[] array)
{
   BitmapImage image = new BitmapImage();
   image.BeginInit();
   image.StreamSource = new System.IO.MemoryStream(array);
   image.EndInit();
   return image;
 }
29

最初のコード例では、画像が実際にロードされる前にストリームが閉じられます(usingブロックを残すことにより)。 BitmapCacheOptions.OnLoad を設定して、画像がすぐにロードされるようにする必要があります。そうしないと、2番目の例のようにストリームを開いたままにする必要があります。

public BitmapImage ToImage(byte[] array)
{
    using (var ms = new System.IO.MemoryStream(array))
    {
        var image = new BitmapImage();
        image.BeginInit();
        image.CacheOption = BitmapCacheOption.OnLoad; // here
        image.StreamSource = ms;
        image.EndInit();
        return image;
    }
}

BitmapImage.StreamSource の備考セクションから:

BitmapImageの作成後にストリームを閉じる場合は、CacheOptionプロパティをBitmapCacheOption.OnLoadに設定します。


それに加えて、組み込み型変換を使用して、型byte[]を入力してImageSource(または派生したBitmapSource):

var bitmap = (BitmapSource)new ImageSourceConverter().ConvertFrom(array);

ImageSourceConverterは、タイプImageSourceのプロパティ(たとえば、イメージコントロールのSourceプロパティ)をタイプstringUriのソースプロパティにバインドするときに暗黙的に呼び出されます。 byte[]

56
Clemens

最初のケースでは、MemoryStreamusingブロックに定義しました。これにより、ブロックから出たときにオブジェクトが破棄されます。そのため、破棄(および存在しない)ストリームでBitmapImageを返します。

MemoryStreamsはアンマネージリソースを保持しないため、メモリを残して、GCに解放プロセスを処理させることができます(ただし、これはお勧めできません)。

4