C# 如何找到通用GDI的原因+;保存图像时出错?

C# 如何找到通用GDI的原因+;保存图像时出错?,c#,.net,image,gdi+,system.drawing,C#,.net,Image,Gdi+,System.drawing,在加载和存储图像时,有一个代码可以使用很长时间,我发现我有一个图像破坏了这个代码: 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.Ex

在加载和存储图像时,有一个代码可以使用很长时间,我发现我有一个图像破坏了这个代码:

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(字符串文件名、ImageCodeInfo编码器、EncoderParameters encoderParams)
在System.Drawing.Image.Save(字符串文件名,图像格式)

就我所见,这张照片没有什么特别之处。它的大小约为250像素,可以在Windows Image Viewer或Paint.NET中打开:

(因为上面的图片在上传到Stack Overflow后不再产生错误,我已经把它放在

我发现,在调用时,目标映像文件是用零字节创建的

我真的不知道是什么原因造成了这个错误

我的问题:

var i = Image.FromFile(i1Path);
File.WriteAllText(i2Path, "empty");  // <---- magic goes here
i.Save(i2Path, ImageFormat.Jpeg);
  • 你能想出什么特别的东西会阻碍.NET保存图像吗
  • 除了惊慌失措之外,还有什么办法缩小这种错误的范围吗

原因可能是图像加载延迟,并且在尝试保存图像时加载过程尚未完成

按照中所说的(假设你是德国人,看你在问题中链接的图片)提供了一个可能的解决方案。接受的回答还表明,这是由于您试图保存到的图像文件被锁定所致

编辑
对于Ulysses Alves,来自链接的博客条目:如果您使用
image.FromFile()
加载图像,它将保持锁定状态,直到被释放。这将防止调用
Save()

上面的代码抛出一个错误

要使其工作,您需要复制图像。以下代码起作用:

pictureBox1.Image = Image.FromFile("C:\\test\\test1.jpg");
Image copy = pictureBox1.Image;
copy.Save("C:\\test\\test2.jpg")

虽然我仍然没有找到保存图像时错误的确切原因,但我找到了一个解决方法:

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);
也就是说,通过在内部将图像复制到实例中并保存此图像而不是原始图像,错误消失

我假设通过复制它,导致原始
Save
调用失败的错误部分将被删除和/或规范化,从而使Save操作成功


有趣的是,如此存储的映像在磁盘上的文件(16 kB)比其原始源(26 kB)小。

首先确保所需文件夹具有读/写权限。更改权限为我解决了这个问题。

解决方案就在这里,您必须处理映像对象以释放服务器上的内存。
尝试使用
语句。确保服务器上的目标目录也存在。

我的解决方案是,在保存文件之前写入临时内容(File.writealtext)

代码如下:

var i = Image.FromFile(i1Path);
File.WriteAllText(i2Path, "empty");  // <---- magic goes here
i.Save(i2Path, ImageFormat.Jpeg);
var i=Image.FromFile(i1Path);
File.writealText(i2Path,“empty”);// 在程序中打开

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();

我发现这个问题是因为我也遇到了类似的错误,文件实际上是用零长度创建的(如果没有看到任何文件,请按照其他答案的建议,首先检查写入文件夹的权限)。虽然我的代码略有不同(我使用
stream
从内存中读取图像,而不是从文件中读取),但我认为我的回答可能对任何面临类似问题的人都有帮助

这看起来可能违反直觉,但在完成映像之前,您无法真正处理内存流

不工作

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);
}
在处理完图像之前不要处理流

有效

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);
}
什么是误导:

  • 错误消息并没有真正告诉您任何事情
  • 您可以看到图像属性,如宽度和高度,但不能 省省吧
关键信息:

// Using System.Drawing.Imaging:
new Bitmap(image).Save(memoryStream, ImageFormat.Jpeg);
必须将图像强制转换为位图才能保存

使用:

// Using System.Drawing.Imaging:
image.Save(memoryStream, ImageFormat.Jpeg);
将抛出错误:

保存图像时出现一般GDI+错误


在我的例子中,我意外地删除了存储图像的目录。

只需使用visual studio作为管理员,或者以管理员身份运行由代码创建的应用程序,它就会正常工作。 这是用户访问权限问题。
我也遇到了同样的问题,并通过以管理员身份运行visual studio解决了这个问题。

我真的不明白为什么这个答案会被否决。。。也许有人可以解释一下?因为那些倒台的选民没有留下评论,我们可能永远也不知道我在链接的帖子中找不到任何与这个主题相关的东西。你能在回答中给我们一个代码示例吗?我猜行Image copy=pictureBox1.Image;不是创建副本,只是创建一个新引用。这听起来像是一个非常糟糕的答案。“确保服务器上的目标目录存在”是我的答案issue@UweKeim-在临时
IDisposable
对象上使用
只会确保在安全的情况下为其调用GC。“确保服务器上的目标目录存在”也是我的问题“确保服务器上的目标目录存在”“这也是我的问题。很容易被忽视。这对我也很有效。我不得不在事后强制垃圾收集,因为这导致了“内存不足异常”。这对我也有效——不知道为什么。只有jpg图像有问题(png等没问题)我在.bmp、.jpg和.png上有问题,但我没有加载文件,而是在内存中创建并试图保存它<代码>原因:
原始位图绑定到从中加载的流(
FileStream
MemoryStream
)。克隆的位图没有绑定到流,因为它复制了像素字节。在保存原始位图之前,冻结原始位图也可能有效。我第二次遇到这个错误,第一次使用与u相同的解决方案时也遇到了一些问题。但是