无法将图像转换为字节[] C#

时间:2010-01-29 04:33:14

标签: c# winforms image

对于将数据保存到数据库中的这些东西我是非常新的,即使我认为它非常直接,但事实并非如此。我要做的是从任何格式的同一台计算机读取和图像文件,将其显示在图片框中,然后将图像转换为字节以将其保存在数据库中。到现在为止,我可以在图片框中显示图像,但我无法将图像转换为字节。这是我的代码:

    private void DisplayImage()
    {
        if (openFileDialog.ShowDialog(this) == DialogResult.OK)
        {
            try
            {
                Stream file;
                if ((archivo = openFileDialog.OpenFile()) != null)
                {
                    using (file)
                    {
                        pictureBox.Image = Image.FromStream(file);
                    }
                }
            }
            catch (Exception ex)
            {
               ...
            }
        }
    }

这是一种只在图片框中显示图像的简单方法。真正的问题是使用以下方法:

    public static byte[] ConvertImageToBytes(Image image)
    {
        if (image != null)
        {
            MemoryStream ms = new MemoryStream();
            using (ms)
            {
                image.Save(ms, ImageFormat.Bmp);
                byte[] bytes = ms.ToArray();

                return bytes;
            }
        }
        else
        {
            return null;
        }
    }

当它试图将图像保存到内存流时,我收到错误:

System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI+.

有关正在发生的事情的任何想法?

5 个答案:

答案 0 :(得分:3)

您应该使用原始图像的RawFormat属性作为Save方法的参数,而不是默认为Bitmap。这样可以避免图像格式类型错误。例如:

    image.Save(ms, image.RawFormat);

    ms.Position = 0;

    byte [] bytes=ms.ToArray();

我建议实际将图像保存到文件系统,只需将文件路径(最好是相对的)存储在数据库中。

数据库中的BLOB(即图像等)无法编入索引,通常存储在次要的,访问速度较慢的数据库区域,并且会快速耗尽数据库的大小(较慢的备份等)。

答案 1 :(得分:2)

你不能简单地读取文件并使用File类将其加载到byte []:

byte[] imgData = System.IO.File.ReadAllBytes(@"C:\My Pic\Myfile.jpg");

您可以从“打开”对话框中选择图像路径。

答案 2 :(得分:1)

该特殊异常通常意味着您尝试将图像保存为错误的格式。在您的代码中指定ImageFormat.Bmp - 它实际上是位图图像,还是您可能从JPEG或PNG加载它?如documentation中所述,尝试以与您加载的格式不同的格式保存ExternalException会失败。

顺便说一句,我不建议将图像存储在数据库中,我相信这里的大多数人会同意。数据库可能能够处理此任务,但它们没有针对它进行优化,最终会损害数据库和应用程序的性能。除非您使用SQL Server 2008 FILESTREAM列,否则在文件系统上存储图像会更有效。

答案 3 :(得分:1)

回答我自己的问题可能是愚蠢的,但我发现如果我想将Image对象转换为字节,我必须将原始流保持打开状态。我在另一个页面中看到了这个问题,我不记得了,我通过打开流来测试它,这是真的。所以格式不是问题。但我会接受你们所有人的建议并将图像存储在一个单独的目录中。谢谢你的帮助!

答案 4 :(得分:0)

这个问题是流必须在图像的生命周期内打开,否则会失败。

一个对我有用的解决方案就是创建一个像这样的图像副本:

using (var ms = new MemoryStream(bytes))
{
    _image = new Bitmap(Image.FromStream(ms));
}