Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se describe cómo copiar una imagen almacenada en una base de datos directamente en un control PictureBox en un formulario Windows Forms sin necesidad de guardar la imagen en un archivo.
Versión original del producto: Visual C#
Número de KB original: 317701
Resumen
En este artículo paso a paso se describe cómo copiar una imagen almacenada en una base de datos directamente en un control PictureBox en un formulario Windows Forms sin necesidad de guardar la imagen en un archivo.
En Visual Basic 6.0, la única manera de mostrar una imagen de una base de datos en un control PictureBox, sin el paso intermedio de guardar los datos del objeto grande binario {BLOB) en un archivo, es enlazar PictureBox a un origen de datos como un control de datos ActiveX Data Objects (ADO) o recordset. No hay ninguna manera (sin enlace de datos) para cargar mediante programación un BLOB en un control sin guardar la imagen en un archivo para su uso por la instrucción LoadPicture.
En este artículo, usaremos el MemoryStream
objeto de la System.IO
clase base para copiar los datos de imagen de la base de datos directamente en el control PictureBox.
Requisitos
En la lista siguiente se describen los hardware, software, infraestructura de red y service packs recomendados que necesitará:
- Visual Studio .NET instalado en un sistema operativo Windows compatible
- Una instancia disponible de SQL Server o una base de datos de Access disponible para pruebas
En este artículo se supone que está familiarizado con los temas siguientes:
- Aplicaciones de Windows Forms de Visual C# para .NET
- Almacenamiento de objetos binarios grandes (BLOB) en bases de datos
- acceso a datos de ADO.NET
Ejemplo
Cree una tabla de SQL Server o Access con la siguiente estructura:
CREATE TABLE BLOBTest ( BLOBID INT IDENTITY NOT NULL, BLOBData IMAGE NOT NULL )
Abra Visual Studio .NET y cree un proyecto de aplicación de Windows de Visual C#.
Agregue un Control PictureBox y dos controles Button al form1 predeterminado del cuadro de herramientas. Establezca la
Text
propiedad de enButton1
Archivo en Base de datos y laText
propiedad deButton2
en Database en PictureBox.Inserte las siguientes instrucciones using en la parte superior del módulo de código del formulario:
using System.Data.SqlClient; using System.IO; using System.Drawing.Imaging;
Agregue la siguiente declaración para la base de datos cadena de conexión justo dentro de la clase pública Form1:
System.Windows.Forms.Form class
declaración y ajuste el cadena de conexión según sea necesario:String strCn = "Data Source=localhost;integrated security=sspi;initial catalog=mydata";
Inserte el código siguiente en el
Click
procedimiento de evento deButton1
(Archivo a base de datos). Ajuste la ruta de acceso del archivo a un archivo de imagen de ejemplo disponible según sea necesario. Este código lee el archivo de imagen del disco (mediante unFileStream
objeto ) en unaByte
matriz y, a continuación, inserta los datos en la base de datos mediante un objeto Command con parámetros.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); }
Inserte el código siguiente en el
Click
procedimiento de evento deButton2
(Database to PictureBox). Este código recupera las filas de la tabla de laBLOBTest
base de datos en ,DataSet
copia la imagen agregada más recientemente en unaByte
matriz y, a continuación, en unMemoryStream
objeto y, a continuación, carga enMemoryStream
laImage
propiedad del control 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); }
Presione F5 para compilar y ejecutar el proyecto.
Haga clic en el botón Archivo a base de datos para cargar al menos una imagen de ejemplo en la base de datos.
Haga clic en el botón Base de datos en PictureBox para mostrar la imagen guardada en el control PictureBox.
Si desea poder insertar la imagen desde el control PictureBox directamente en la base de datos, agregue un tercer control Button e inserte el código siguiente en su
Click
procedimiento de evento. Este código recupera los datos de imagen del control PictureBox en unMemoryStream
objeto , copia enMemoryStream
unaByte
matriz y, a continuación, guarda laByte
matriz en la base de datos mediante un objeto Command con parámetros.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); }
Ejecuta el proyecto . Haga clic en el botón Base de datos en PictureBox para mostrar una imagen guardada previamente en el control PictureBox. Haga clic en el botón recién agregado para guardar la imagen de PictureBox en la base de datos. A continuación, haga clic de nuevo en el botón Base de datos en PictureBox para confirmar que la imagen se guardó correctamente.
Trampas
Esta prueba no funcionará con la columna Photo de la tabla Employees de la base de datos Northwind de ejemplo distribuida con Access y SQL Server. Las imágenes de mapa de bits almacenadas en la columna Photo se encapsulan con la información de encabezado creada por el control Contenedor OLE de Visual Basic 6.0.
Si necesita usar una base de datos de Access para probar este código, deberá crear la columna en la tabla de Access como objeto OLE y usar el
System.Data.OleDb
espacio de nombres con el proveedor Jet 4.0 en lugar delSystem.Data.SqlClient
espacio de nombres.