好的,对不起,这可能是一个菜鸟问题,但我有点卡住了。
所以我正在做的(在我的asp.net应用程序上)是从文件系统加载图像:
System.Drawing.Image tempImage;
tempImage = System.Drawing.Image.FromFile(HttpContext.Server.MapPath(originalPath));
然后我做了一些调整大小:
tempImage = my awesomeResizingFunction(tempImage, newSize);
并打算使用以下方法将其保存到其他位置的文件系统中:
string newPath = "/myAwesomePath/newImageName.jpg";
tempImage.Save(newPath);
我得到的是这个错误:
"A generic error occurred in GDI+."
我知道图像是“正常”,因为我可以将其写入浏览器并查看已调整大小的图像,我只是在尝试保存时才会收到错误。我有点新手,我完全错了吗? (好吧,我猜这很明显,但你知道我的意思......)
答案 0 :(得分:7)
请尝试此代码...我使用了相同的代码来调整图像大小和保存。如果你有任何问题,请告诉我。
System.Drawing.Bitmap bmpOut = new System.Drawing.Bitmap(NewWidth, NewHeight);
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmpOut);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.FillRectangle(System.Drawing.Brushes.White, 0, 0, NewWidth, NewHeight);
g.DrawImage(new System.Drawing.Bitmap(fupProduct.PostedFile.InputStream), 0, 0, NewWidth, NewHeight);
MemoryStream stream = new MemoryStream();
switch (fupProduct.FileName.Substring(fupProduct.FileName.IndexOf('.') + 1).ToLower())
{
case "jpg":
bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
break;
case "jpeg":
bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
break;
case "tiff":
bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Tiff);
break;
case "png":
bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
break;
case "gif":
bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Gif);
break;
}
String saveImagePath = Server.MapPath("../") + "Images/Thumbnail/" + fupProduct.FileName.Substring(fupProduct.FileName.IndexOf('.'));
bmpOut.Save(saveImagePath);
其中fupProduct是fileupload控件ID
答案 1 :(得分:4)
您确定originalPath和newPath指向不同的文件吗?当您使用Image.FromFile时,文件将保持锁定状态,直到您在Image上调用Dispose,这可能会导致您提到的异常。您可以这样加载图像:
Image tempImage = null;
using (FileStream fs = new FileStream(originalPath, FileMode.Open, FileAccess.Read))
{
tempImage = Image.FromStream(fs);
}
...
此方法可确保在使用块结束时关闭文件
答案 2 :(得分:0)
支持原始图像的原始流是否可能已关闭?如果Bitmap后面的流已关闭,则会开始出现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;