原始图像后面的流是否已关闭?如果Bitmap后面的流已关闭,则会出现GDI+错误。当我们将图像处理添加到网站时,我经常遇到这种情况。
如果您在Visual Studio调试器中打开Bitmap对象,是否看到异常而不是属性值?如果是这样,那么问题不在于保存操作,而是GDI+层已经失去了处理该对象的能力。
我发现我需要跟踪属于我的位图的MemoryStreams并将它们全部保持在一起。调整图像大小会导致具有新Bitmap图像的新MemoryStream。
最终,我创建了这个简单的类(修剪了一些不需要的额外属性):
public class UploadedImage : IDisposable
{
private Bitmap _img = null;
private Stream _baseStream = null;
public Bitmap Img
{
[DebuggerStepThrough]
get { return _img; }
[DebuggerStepThrough]
set { _img = value; }
}
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);
Rectangle rect = new Rectangle(0, 0, newWidth, newHeight);
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.SmoothingMode = SmoothingMode.HighSpeed;
gr.PageUnit = GraphicsUnit.Pixel;
gr.DrawImage(img, rect);
retval = new UploadedImage();
retval.BaseStream = (Stream)(new MemoryStream());
temp.Save(retval.BaseStream, ImageFormat.Jpeg);
retval.Img = temp;