我正在开发一个简单的图形应用程序。上传图片,编辑图片,然后保存。我尝试了各种方法,但都以某种方式失败。
我首先尝试了像这样加载位图。
imageFromName = new Bitmap(FileName1);
然后像这样保存
imageFromName.Save(FileName1);
但它抛出了一个 "GDI +. "的异常.另外,此时windows资源管理器不允许我删除文件,所以我认为问题是 "imageFromName "对象保持文件打开,不允许覆盖它,所以我修改了这样的代码。
imageFromName = new Bitmap(FileName1);
imageCloned = (Bitmap)imageFromName.Clone();
imageFromName.Dispose();
imageCloned.Save(FileName1);
程序一直在抛出同样的异常 imageCloned.Save (FileName1)
于是我在Stackoverflow上寻找帮助,看到了几个类似的问题,答案都是建议检查应用是否有写权限。于是我修改了代码,像这样检查。
imageFromName = new Bitmap(FileName1);
imageFromName.Save(FileName2);
在这种情况下,程序在保存文件的时候没有抛出任何异常 但我还是不能修改原来的文件 也不能用Windows资源管理器删除它。它只是为我创建了一个文件的副本。
所以我想用另一种方式加载位图,并修改了这样的代码。
try
{
System.IO.FileStream fs = new System.IO.FileStream(FileName1, System.IO.FileMode.Open);
imageFromStream = new System.Drawing.Bitmap(fs);
fs.Close();
}
catch (Exception ex)
{
Console.WriteLine("Error loading Bitmap.", ex);
}
在这种情况下,应用程序没有抛出任何异常,位图在PictureBox中也能很好地被看到。另外,资源管理器允许我删除文件。然而,当我用 imageFromStream.Save (imageFromStream)
它一直为我生成一个异常。
这次的不同之处在于 Save ()
方法,尽管抛出了异常,但还是会覆盖原始文件,反而生成了一个包含头信息的 54 字节文件。
用十六进制编辑器打开原始文件和副本文件,我验证了除了图像大小和BITMAPINFOHEADER的偏移量之外,头信息是一样的。只有图纸的信息没有了。
我已经阅读了微软官方文档中关于 System.Drawing.Bitmap.Save ()
方法,并且没有发现任何形式的限制。但我想说,它对某些像素格式有问题。
然而,我希望不必将我的应用程序限制在32bpp文件上,那么。
1 -什么是最好的方法来保存一个图像的图像?System.Drawing.Bitmap
对象到一个24bpp文件?
2-System.Drawing.Bitmap.Save()还有什么限制吗?
当你从存储在硬盘上的图像中初始化一个位图对象时,它会在底层图像文件上创建一个锁。由于锁定,当你尝试保存修改后的位图时,它会抛出这个错误。
有两种方法可以解决这个问题
保存图像到24bpp文件的最好方法是使用以下方法 PixelFormat.Format24bppRgb
为新的位图对象。
这里是一个例子。
using Bitmap imageCopy = null;
using(var imageFromName = new Bitmap(FileName1))
{
// you can modify your image here
...
// Before this block ends we need to copy Bitmap
imageCopy = new Bitmap(imageFromName); // or imageFromName.Clone with expected format
}
imageCopy.Save(FileName1);
另一种方法是在编辑时没有文件系统锁定的情况下即时读取图像。
using(var ms = new MemoryStream(File.ReadAllBytes(FileName1))
using(var image = new Bitmap(ms))
{
// you can modify your image here
...
image.Save(FileName1);
}