这是我的序列化,反序列化并将图像保存到文件系统的代码。我看过许多序列化/反序列化的示例,我只是想获得一些反馈,因为我确信我的代码可以改进。任何反馈将不胜感激。我知道这是一个普遍的问题,因此希望这个问题将来对其他人是一个很好的资源。
这是使用建议的修订代码:
private void Form1_Load(object sender, EventArgs e)
{
RunTest();
}
private void RunTest()
{
byte[] jpgba = ConvertFileToByteArray("D:\\Images\\Image01.jpg");
using (Image jpgimg = ConvertByteArrayToImage(jpgba))
{
SaveImageToFileSystem(jpgimg, "D:\\Images\\Image01_Copy.jpg");
}
byte[] pngba = ConvertFileToByteArray("D:\\Images\\Image02.png");
using (Image pngimg = ConvertByteArrayToImage(pngba))
{
SaveImageToFileSystem(pngimg, "D:\\Images\\Image02_Copy.png");
}
byte[] gifba = ConvertFileToByteArray("D:\\Images\\Image03.gif");
using (Image gifimg = ConvertByteArrayToImage(gifba))
{
SaveImageToFileSystem(gifimg, "D:\\Images\\Image03_Copy.gif");
}
MessageBox.Show("Test Complete");
this.Close();
}
private static byte[] ConvertFileToByteArray(String FilePath)
{
return File.ReadAllBytes(FilePath);
}
private static Image ConvertByteArrayToImage(byte[] ImageByteArray)
{
using (MemoryStream ms = new MemoryStream(ImageByteArray))
{
return Image.FromStream(ms);
}
}
private static void SaveImageToFileSystem(Image ImageObject, string FilePath)
{
// ImageObject.Save(FilePath, ImageObject.RawFormat);
// This method only works with .png files.
// This method works with .jpg, .png and .gif
// Need to copy image before saving.
using (Image img = new Bitmap(ImageObject.Width, ImageObject.Height))
{
using (Graphics tg = Graphics.FromImage(img))
{
tg.DrawImage(ImageObject, 0, 0);
}
img.Save(FilePath, img.RawFormat);
}
return;
}
最佳答案
我从快速浏览中看到的是:
流应使用using(...)模式进行包装,如果您在处理过程中发生异常,则不会调用Dispose()。
using (FileStream fs = new FileStream(FilePath, FileMode.Open))
{
// Another small optimization, removed unnecessary variable
byte[] iba = new byte[(int)fs.Length];
fs.Read(iba, 0, iba.Length);
}
您应该仅捕获预期的异常。例如,在SerializeImage中,这将是IOException。捕获所有异常是非常不好的做法。
}
catch (IOException ex)
{
Image.FromStream方法取决于流,因此,如果关闭基础流并返回Image,则可能会收到无法预料的行为(嗯,在大多数情况下,这是可行的,但有时会发生错误)。因此,您需要创建图像副本并返回它。
using (MemoryStream ms = new MemoryStream(ImageByteArray))
{
using (Image img = Image.FromStream(ms))
{
return new Bitmap(img);
}
}
您不会在SaveImage方法中放置tg图形对象和img对象(但会放置ImageObject,请参见下一段)。通常,我认为这种逻辑没有必要,如果要保存图像保留质量,只需调用ImageObject.Save(...,ImageFormat.Png)。
在相同的方法(SaveImage)中,您将放置ImageObject参数。在大多数情况下,这也是一种不好的做法,请考虑通过使用using(...)模式将该图像放置在worker方法之外。