9

BitmapImageaを aに変換するには、次の方法がありますSystem.Drawing.Bitmap

public static Bitmap BitmapImageToBitmap(BitmapImage bitmapImage)
{
    Bitmap bitmap;

    using (var ms = new MemoryStream())
    {
        var encoder = new JpegBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
        encoder.Save(ms);

        bitmap = new Bitmap(ms);
    }

    return bitmap;
}

返された Bitmap オブジェクトを使用しようとすると、次のエラーが発生します。

OutOfMemoryException が発生しました - メモリ不足です。

ただし、コードをこれに置き換えるたびに:

public static Bitmap BitmapImageToBitmap(BitmapImage bitmapImage)
{
    var ms = new MemoryStream();

    var encoder = new JpegBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(bitmapImage));

    encoder.Save(ms);

    return new Bitmap(ms);
}

これはうまくいきます。ただし、オブジェクトの実装としてusingを使用することになっていると確信しています。何が起きてる?MemoryStreamIDisposable

4

2 に答える 2

11

Bitmap のコンストラクターBitmap Constructor (Stream)は、

Bitmap の存続期間中、ストリームを開いたままにしておく必要があります。

あなたの場合、usingステートメントを使用している場合、ストリーム(使い捨て)は自動的に破棄されるため、 Bitmap オブジェクトは無効になります。メモリを割り当てすぎているということではありませんが、ビットマップが存在しないものを指しているということです。

于 2013-01-21T13:21:19.367 に答える
1

@Tigranが言ったことは完全に正しいので、@CodesInChaos の回避策を次のように実装しまし

public static Bitmap BitmapImageToBitmap(BitmapImage bitmapImage)
{
    Bitmap bitmap;

    using (var ms = new MemoryStream())
    {
        var encoder = new JpegBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
        encoder.Save(ms);

        using (var localBitmap = new Bitmap(ms))
        {
            bitmap = localBitmap.Clone(new Rectangle(0, 0, localBitmap.Width, localBitmap.Height),
                   PixelFormat.Format32bppArgb);  
        }
    }

    return bitmap;
}
于 2013-01-21T13:28:22.180 に答える