[英]How to find reason for Generic GDI+ error when saving an image?
有一个在加载和存储图像时可以使用很长时间的代码,我发现我有一个破坏此代码的单个图像:
const string i1Path = @"c:\my\i1.jpg";
const string i2Path = @"c:\my\i2.jpg";
var i = Image.FromFile(i1Path);
i.Save(i2Path, ImageFormat.Jpeg);
例外是:
System.Runtime.InteropServices.ExternalException 发生
GDI+ 中出现一般错误。
在 System.Drawing.Image.Save(字符串文件名,ImageCodecInfo 编码器,EncoderParameters 编码器参数)
在 System.Drawing.Image.Save(字符串文件名,ImageFormat 格式)
在 ...
就我所见,图像没有什么特别之处。 它的大小约为 250 像素,可以在例如 Windows Image Viewer 或 Paint.NET 中打开:
(因为上图上传到Stack Overflow后不再报错,我把原图放在这里)
我发现在调用Save
方法时,目标图像文件是用零字节创建的。
我真的对导致错误的原因一无所知。
我的问题:
虽然我仍然没有找出保存图像时究竟是什么导致错误的原因,但我找到了一个解决方法:
const string i1Path = @"c:\my\i1.jpg";
const string i2Path = @"c:\my\i2.jpg";
var i = Image.FromFile(i1Path);
var i2 = new Bitmap(i);
i2.Save(i2Path, ImageFormat.Jpeg);
即通过将图像内部复制Bitmap
实例并保存此图像而不是原始图像,错误消失了。
我假设通过复制它,导致原始Save
调用失败的错误部分被删除和/或规范化,从而使保存操作成功。
有趣的是,如此存储的图像在磁盘上的文件 (16 kB) 比其原始源 (26 kB) 小。
首先确保所需的文件夹具有读/写权限。 更改权限为我解决了这个问题。
解决方案在这里,您必须处理图像对象以释放服务器上的内存。 尝试使用using
语句。 确保服务器上的目标目录也存在。
原因可能是图像加载延迟,尝试保存时加载过程尚未完成。
按照这篇博文中所说的(假设你在问题中链接的图片是德国人)提供了一个可能的解决方案。 此外, 此问题已接受的答案表明这是由于您尝试保存的图像文件已被锁定。
编辑
对于 Ulysses Alves,来自链接的博客条目:如果您使用Image.FromFile()
加载图像,它将保持锁定状态,直到它被处理掉。 这可以防止调用Save()
。
pictureBox1.Image = Image.FromFile("C:\\test\\test1.jpg");
pictureBox1.Image.Save("C:\\test\\test2.jpg");
上面的代码抛出一个错误。
要使其工作,您需要复制图像。 以下代码有效:
pictureBox1.Image = Image.FromFile("C:\\test\\test1.jpg");
Image copy = pictureBox1.Image;
copy.Save("C:\\test\\test2.jpg")
我发现这个问题是因为我也遇到了类似的错误,并且文件实际上是用零长度创建的(如果您没有看到任何文件,请首先检查写入文件夹的权限,如其他答案所建议的那样)。 尽管我的代码略有不同(我使用stream
从内存中读取图像,而不是从文件中读取图像),但我认为我的回答可能对任何面临类似问题的人有所帮助。
它可能看起来违反直觉,但在完成 image 之前,您无法真正处理内存流。
不工作:
Image patternImage;
using (var ms = new MemoryStream(patternBytes)) {
patternImage = new Bitmap(ms);
}
patternImage.Save(patternFile, ImageFormat.Jpeg);
在完成图像之前不要处理流。
作品:
using (var ms = new MemoryStream(patternBytes)) {
patternImage = new Bitmap(ms);
patternImage.Save(patternFile, ImageFormat.Jpeg);
}
什么是误导:
我的解决方案是在保存文件之前制作,写入临时内容(File.WriteAllText)
这是代码:
var i = Image.FromFile(i1Path);
File.WriteAllText(i2Path, "empty"); // <---- magic goes here
i.Save(i2Path, ImageFormat.Jpeg);
请尝试让我知道
就我而言,我不小心删除了存储图像的目录。
只需以管理员身份使用visual studio或以管理员身份运行由代码创建的应用程序,它应该可以顺利运行。 这是用户访问权限问题。 我遇到了同样的问题,并通过以管理员身份运行 Visual Studio 来解决它。
在程序中打开
const string i1Path = @"c:\my\i1.jpg";
const string i2Path = @"c:\my\i2.jpg";
var i = Image.FromFile(i1Path);
i.Save(i2Path, ImageFormat.Jpeg);
i.Dispose();
关键信息:
// Using System.Drawing.Imaging:
new Bitmap(image).Save(memoryStream, ImageFormat.Jpeg);
您必须将图像投射到位图才能保存它。
使用:
// Using System.Drawing.Imaging:
image.Save(memoryStream, ImageFormat.Jpeg);
将抛出错误:
保存图像时出现通用 GDI+ 错误
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.