本文介绍如何将数据库中存储的图像直接复制到 Windows 窗体上的 PictureBox 控件中,而无需将图像保存到文件中。
原始产品版本: Visual C#
原始 KB 数: 317701
总结
本分步文章介绍如何将数据库中存储的图像直接复制到 Windows 窗体上的 PictureBox 控件中,而无需将图像保存到文件中。
在 Visual Basic 6.0 中,在 PictureBox 控件中显示来自数据库的图像的唯一方法是将二进制大型对象 {BLOB) 数据保存到文件中的中间步骤是将 PictureBox 绑定到 ActiveX 数据对象(ADO)数据控件或记录集等数据源。 无法(没有数据绑定)以编程方式将 BLOB 加载到控件中,而无需将图像保存到文件以供 LoadPicture 语句使用。
在本文中,我们将使用 MemoryStream
基类中的 System.IO
对象将图像数据从数据库直接复制到 PictureBox 控件中。
要求
以下列表概述了所需的推荐硬件、软件、网络基础结构和服务包:
- 在兼容的 Windows 操作系统上安装的 Visual Studio .NET
- SQL Server 的可用实例或可用于测试的 Access 数据库
本文假定你熟悉以下主题:
- Visual C# .NET Windows 窗体应用程序
- 数据库中的二进制大型对象 (BLOB) 存储
- ADO.NET 数据访问
示例
使用以下结构创建 SQL Server 或 Access 表:
CREATE TABLE BLOBTest ( BLOBID INT IDENTITY NOT NULL, BLOBData IMAGE NOT NULL )
打开 Visual Studio .NET 并创建新的 Visual C# Windows 应用程序项目。
从工具箱将 PictureBox 和两个按钮控件添加到默认 Form1。 将
Text
“文件”的属性Button1
设置为“数据库”,并将Text
“数据库”的属性Button2
设置为 PictureBox。在窗体代码模块顶部插入以下 using 语句:
using System.Data.SqlClient; using System.IO; using System.Drawing.Imaging;
在公共类 Form1 中为数据库添加以下声明连接字符串:
System.Windows.Forms.Form class
声明并根据需要调整连接字符串:String strCn = "Data Source=localhost;integrated security=sspi;initial catalog=mydata";
在事件过程中
Button1
插入以下代码Click
(文件到数据库)。 根据需要将文件路径调整为可用的示例图像文件。 此代码将图像文件从磁盘(使用FileStream
对象)读取到Byte
数组中,然后使用参数化的 Command 对象将数据插入数据库中。try { SqlConnection cn = new SqlConnection(strCn); SqlCommand cmd = new SqlCommand("INSERT INTO BLOBTest (BLOBData) VALUES (@BLOBData)", cn); String strBLOBFilePath = @"C:\blue hills.jpg";//Modify this path as needed. //Read jpg into file stream, and from there into Byte array. FileStream fsBLOBFile = new FileStream(strBLOBFilePath,FileMode.Open, FileAccess.Read); Byte[] bytBLOBData = new Byte[fsBLOBFile.Length]; fsBLOBFile.Read(bytBLOBData, 0, bytBLOBData.Length); fsBLOBFile.Close(); //Create parameter for insert command and add to SqlCommand object. SqlParameter prm = new SqlParameter("@BLOBData", SqlDbType.VarBinary, bytBLOBData.Length, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, bytBLOBData); cmd.Parameters.Add(prm); //Open connection, execute query, and close connection. cn.Open(); cmd.ExecuteNonQuery(); cn.Close(); } catch(Exception ex) { MessageBox.Show(ex.Message); }
在事件过程中
Button2
插入以下代码Click
(数据库到 PictureBox)。 此代码从数据库中的BLOBTest
表中检索行,DataSet
将最近添加的图像Byte
复制到数组中,然后复制到对象MemoryStream
中,然后加载到MemoryStream
Image
PictureBox 控件的属性中。try { SqlConnection cn = new SqlConnection(strCn); cn.Open(); //Retrieve BLOB from database into DataSet. SqlCommand cmd = new SqlCommand("SELECT BLOBID, BLOBData FROM BLOBTest ORDER BY BLOBID", cn); SqlDataAdapter da = new SqlDataAdapter(cmd); DataSet ds = new DataSet(); da.Fill(ds, "BLOBTest"); int c = ds.Tables["BLOBTest"].Rows.Count; if(c>0) { //BLOB is read into Byte array, then used to construct MemoryStream, //then passed to PictureBox. Byte[] byteBLOBData = new Byte[0]; byteBLOBData = (Byte[])(ds.Tables["BLOBTest"].Rows[c - 1]["BLOBData"]); MemoryStream stmBLOBData = new MemoryStream(byteBLOBData); pictureBox1.Image= Image.FromStream(stmBLOBData); } cn.Close(); } catch(Exception ex) { MessageBox.Show(ex.Message); }
按 F5 编译并运行项目。
单击“文件到数据库”按钮,将至少一个示例图像加载到数据库中。
单击“数据库到 PictureBox”按钮,在 PictureBox 控件中显示保存的图像。
如果希望能够将图片从 PictureBox 控件直接插入到数据库中,请添加第三个 Button 控件并在其
Click
事件过程中插入以下代码。 此代码将 PictureBox 控件中的图像数据检索到对象MemoryStream
中,将图像数据复制到MemoryStream
Byte
数组中,然后使用参数化的 Command 对象将Byte
数组保存到数据库。try { SqlConnection cn = new SqlConnection(strCn); SqlCommand cmd = new SqlCommand("INSERT INTO BLOBTest (BLOBData) VALUES (@BLOBData)", cn); //Save image from PictureBox into MemoryStream object. MemoryStream ms = new MemoryStream(); pictureBox1.Image.Save(ms, ImageFormat.Jpeg); //Read from MemoryStream into Byte array. Byte[] bytBLOBData = new Byte[ms.Length]; ms.Position = 0; ms.Read(bytBLOBData, 0, Convert.ToInt32(ms.Length)); //Create parameter for insert statement that contains image. SqlParameter prm = new SqlParameter("@BLOBData", SqlDbType.VarBinary, bytBLOBData.Length, ParameterDirection.Input, false, 0, 0,null, DataRowVersion.Current, bytBLOBData); cmd.Parameters.Add(prm); cn.Open(); cmd.ExecuteNonQuery(); cn.Close(); } catch(Exception ex) { MessageBox.Show(ex.Message); }
运行该项目。 单击“ 数据库到 PictureBox”按钮,在 PictureBox 控件中显示以前保存的图像。 单击新添加的按钮将图片从 PictureBox 保存到数据库中。 然后再次单击“ 数据库到 PictureBox ”按钮,确认图像已正确保存。
陷阱
此测试不适用于使用 Access 和 SQL Server 分发的示例 Northwind 数据库的 Employees 表中的照片列。 存储在“照片”列中的位图图像用 Visual Basic 6.0 OLE 容器控件创建的标头信息进行包装。
如果需要使用 Access 数据库来测试此代码,则需要将 Access 表中的列创建为类型 OLE 对象,并将
System.Data.OleDb
命名空间与 Jet 4.0 提供程序一起使用来代替System.Data.SqlClient
命名空间。