元の画像を裏付ける元のストリームが閉じられている可能性はありますか?ビットマップの背後にあるストリームが閉じられている場合、GDI+エラーが発生し始めます。私たちのウェブサイトに画像処理を追加したとき、私はこれにたくさん遭遇しました。
Visual Studioデバッガーでビットマップオブジェクトを開くと、プロパティの値の代わりに例外が表示されますか?その場合、保存操作に問題はありませんが、GDI+レイヤーはオブジェクトを処理する機能を失っています。
私が見つけたのは、ビットマップに属するMemoryStreamsを追跡し、それらをすべて一緒に保持する必要があるということでした。画像のサイズを変更すると、新しいビットマップ画像を含む新しいMemoryStreamが作成されました。
私はこの単純なクラスを作成することになりました(ここで不要ないくつかの余分なプロパティをトリミングしました):
public class UploadedImage : IDisposable
{
private Bitmap _img = null;
private Stream _baseStream = null;
/// <summary>
/// The image object. This must always belong to BaseStream, or weird things can happen.
/// </summary>
public Bitmap Img
{
[DebuggerStepThrough]
get { return _img; }
[DebuggerStepThrough]
set { _img = value; }
}
/// <summary>
/// The stream that stores the image. This must ALWAYS belong to Img, or weird things can happen.
/// </summary>
public Stream BaseStream
{
[DebuggerStepThrough]
get { return _baseStream; }
[DebuggerStepThrough]
set { _baseStream = value; }
}
[DebuggerStepThrough]
public void Dispose()
{
if (Img != null)
Img.Dispose();
if (BaseStream != null)
BaseStream.Close();
_attached = false;
}
}
今、私はWebサイトにアップロードされた画像を処理していましたが、Asp.Netがリクエストに添付されたストリームをリサイクルすると、突然の画像操作がすべて飛び出し始めたことがわかりました。したがって、これが最善の方法であるかどうかにかかわらず、私の解決策は、アップロードストリームから自分のMemoryStreamにデータをコピーし、そこから画像をロードして、両方をこのコンテナに貼り付けることでした。また、古い画像から新しい画像を作成する場合は常に、ストリームと画像を一緒に保持していました。
これがお役に立てば幸いです。
編集:私はあなたが画像のサイズ変更をどのように行っているかを見ることにも興味があります。これは、私が行った方法の抜粋です。
temp = new Bitmap(newWidth, newHeight, PIXEL_FORMAT);
temp.SetResolution(newHorizontalRes, newVerticalRes);
gr = Graphics.FromImage(temp);
//
// This copies the active frame from 'img' to the new 'temp' bitmap.
// Also resizes it and makes it super shiny. Sparkle on, mr image dude.
//
Rectangle rect = new Rectangle(0, 0, newWidth, newHeight);
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.SmoothingMode = SmoothingMode.HighSpeed;
gr.PageUnit = GraphicsUnit.Pixel;
gr.DrawImage(img, rect);
//
// Image copied onto the new bitmap. Save the bitmap to a fresh memory stream.
//
retval = new UploadedImage();
retval.BaseStream = (Stream)(new MemoryStream());
temp.Save(retval.BaseStream, ImageFormat.Jpeg);
retval.Img = temp;