支持原始图像的原始流是否可能已关闭?如果位图后面的流已关闭,您将开始收到 GDI+ 错误。当我们将图像处理添加到我们的网站时,我经常遇到这种情况。
如果您在 Visual Studio 调试器中打开 Bitmap 对象,您是否看到异常而不是属性值?如果是这样,则不是保存操作有问题,而是GDI+层失去了处理对象的能力,句号。
我发现我需要跟踪属于我的位图的 MemoryStream 并将它们放在一起。调整图像大小会产生一个带有新位图图像的新 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;
}
}
现在,我正在处理上传到我们网站的图像,我发现当 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;