2010-01-29 44 views
4

我对将图像保存到数据库的这种东西很陌生,甚至当我认为这是非常直截了当的时候,事实并非如此。我想要做的是从同一台计算机以任何格式读取图像文件,并将其显示在图片框中,然后将图像转换为字节以将其保存在数据库中。到目前为止,我可以在图片框中显示图像,但我无法将图像转换为字节。这是我的代码:无法将图像转换为字节[] C#

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+. 

上发生了什么任何想法?

+0

是错误总是发生,或者只是偶尔,或者使用时间长的申请后? – Chris 2010-01-29 05:16:28

+0

你永远不会在第一个方法中分配'文件'变量......我认为这只是真实代码的一个提取?否则,编译器会抱怨在分配之前使用'文件'变量? – 2010-01-29 06:40:31

回答

1

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

1

这种特殊的异常通常意味着您正试图将图像保存为错误的格式。在你的代码中,你指定ImageFormat.Bmp - 它实际上是一个位图图像,还是你可能从JPEG或PNG加载它?试图保存为您加载的格式不同于ExternalException将会失败,如documentation中所述。顺便说一句,我不建议将图像存储在数据库中,我相信这里的大多数人会同意。数据库可能能够处理这个任务,但它们并未针对它进行优化,最终会损害数据库和应用程序的性能。除非您使用SQL Server 2008 FILESTREAM列,否则在文件系统上存储图像效率更高。

+0

+1 - 我怀疑是一样的。图像格式不匹配。 – Gishu 2010-01-29 05:03:58

3

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

image.Save(ms, image.RawFormat); 

    ms.Position = 0; 

    byte [] bytes=ms.ToArray(); 

我建议实际上保存图像的文件系统并简单地在数据库中存储的文件路径(优选相对)。

数据库中的BLOB(即图像等)无法编入索引,通常存储在辅助的较慢访问数据库区域,并且会很快将数据库的大小(比较慢的备份等)吹掉。

2

广东话您只需阅读文件,然后使用File类加载到一个byte []:

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

你可以选择从打开的对话框中的图像路径。

0

这样做的问题是该流必须在映像的生命周期中打开,否则将失败。为我工作

一种解决方案是只是为了创造这样的图像的副本:

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