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