对序列化,反序列化和保存图像的代码的反馈 [英] Feedback on code to Serialize, Deserialize and Save Image

查看:99
本文介绍了对序列化,反序列化和保存图像的代码的反馈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码,用于序列化,反序列化和将图像保存到文件系统。我已经查看了许多序列化/反序列化的例子,我只想得到一些反馈,因为我确信我的代码可以得到改进。任何反馈将不胜感激。我知道这是一个常见的问题,所以希望这个问题对未来的其他人来说是一个很好的资源。

Here is my code to Serialize, Deserialize and Save an image to the file system. I have looked at many examples of serialization/deserialization and I just want to get some feedback as I am sure my code could be improved. Any feedback would be greatly appreciated. I know this is a common problem so hopefully this question will be a good resource for others in the future.

这是修改后的代码使用建议:

    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;
    }


推荐答案

我从快速看到的看看:

Streams应该包含在中使用(...)模式,在你的情况下,如果在处理过程中发生异常,那么Dispose()将不会被调用。

Streams should be wrapped in using(...) pattern, in your case if exception occurs during processing, then Dispose() won't be called.

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 。捕获所有异常是非常糟糕的做法。

You should catch only exceptions you expect. For example in SerializeImage this will be IOException. Catching all exceptions is very bad practice.

}
catch (IOException ex)
{

Image.FromStream方法依赖于流,因此如果关闭基础流并返回Image,则可能会收到不可预测的行为(以及,在大多数情况下,这将起作用,但有时会发生错误)。因此,您需要创建图像副本并将其返回。

Image.FromStream method depends on stream, so if you close underlying stream and return Image you can receive unpredictable behavior (well, in most cases this will work, but sometimes error occurs). So you need to create image copy and return it.

using (MemoryStream ms = new MemoryStream(ImageByteArray))
{
    using (Image img = Image.FromStream(ms))
    {
        return new Bitmap(img);
    }
}

你没有处理tg图形对象和img对象SaveImage方法(但配置ImageObject,见下一段)。一般来说,我没有看到这种逻辑的必要性,如果你想保存图像保存质量,只需调用ImageObject.Save(...,ImageFormat.Png)。

You are not disposed tg graphics object and img object in SaveImage method (but disposed ImageObject, see next paragraph). And in general I do not see necessity in such logic, simply call ImageObject.Save(..., ImageFormat.Png) if you want to save image preserving quality.

在同一方法(SaveImage)中,您将处置ImageObject参数。在大多数情况下这也是不好的做法,考虑使用使用(...)模式在工作方法外部处理此图像。

In the same method (SaveImage) you are disposed ImageObject parameter. This is also bad practice in most cases, consider disposing this image outside worker method by using using(...) pattern.

这篇关于对序列化,反序列化和保存图像的代码的反馈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆