Microsoft KB Archive/321900

From BetaArchive Wiki

Article ID: 321900

Article Last Modified on 7/15/2004



APPLIES TO

  • Microsoft .NET Framework 1.1 Service Pack 1
  • Microsoft ADO.NET 1.1
  • Microsoft Visual Basic .NET 2002 Standard Edition
  • Microsoft Visual Basic .NET 2003 Standard Edition



This article was previously published under Q321900

SUMMARY

This step-by-step article describes how to display an image that is stored in a database in a PictureBox control on a Windows Form.

In Microsoft Visual Basic 6.0, the only way to display an image from a database in a PictureBox control, without the intermediate step of saving the binary large object (BLOB) data to a file, is to bind the PictureBox to a data source such as an ActiveX Data Objects (ADO) data control or Recordset object. Without data binding, you cannot programmatically load a BLOB in a control without saving the image to a file for the LoadPicture statement to use.

The sample in this article uses a Byte array and the MemoryStream object from the System.IO base class to copy the image data from the database directly from an ADO.NET DataSet or DataReader object to the PictureBox control.

back to the top

Requirements

The following list outlines the recommended hardware, software, network infrastructure, and service packs that are required:

  • Microsoft Visual Studio .NET installed on a compatible Microsoft Windows operating system
  • Available instance of Microsoft SQL Server or an available Microsoft Access database for testing

This article assumes that you are familiar with the following topics:

  • Visual Basic .NET Windows Forms applications
  • ADO.NET data access
  • Binary large object (BLOB) storage in databases

back to the top

Create the Visual Basic .NET Sample

  1. Create a SQL Server table or an Access table with the following structure:

    CREATE TABLE BLOBTest
    (
    BLOBID INT IDENTITY NOT NULL,
    BLOBData IMAGE NOT NULL
    )
                        
  2. Follow these steps to create a new Visual Basic Windows Forms application:
    1. Start Visual Studio .NET.
    2. On the File menu, point to New, and then click Project.
    3. In the New Project dialog box, click Visual Basic Projects under Project Types, and then click Windows Application under Templates.
  3. Drag a PictureBox control and two Button controls from the toolbox to the default form, Form1. Change the Name property of the PictureBox to picBlob. Set the Text property of Button1 to File to Database, and then set the Text property of Button2 to Database to PictureBox.
  4. Add the following Imports statements at the top of the Form1 code module:

    Imports System.Data
    Imports System.Data.SqlClient
    Imports System.IO
    Imports System.Drawing.Imaging
                        
  5. Add the following declaration for the database connection string below Public Class Form1, and then modify the connection string as necessary for your environment:

        Dim strCn As String = "Data Source=<server>;" & _
                "Initial Catalog=<database>;Integrated Security=SSPI"
                        
  6. Add the following code in the Click event procedure of Button1, and then modify the file path to an available sample image file as necessary:

            Dim cn As New SqlConnection(strCn)
            Dim cmd As New SqlCommand("INSERT INTO BLOBTest (BLOBData) " & _
                "VALUES (@BLOBData)", cn)
            Dim strBLOBFilePath As String = _
                "C:\Documents and Settings\All Users\Documents" & _
                "\My Pictures\Sample Pictures\winter.jpg"
            Dim fsBLOBFile As New FileStream(strBLOBFilePath, _
                FileMode.Open, FileAccess.Read)
            Dim bytBLOBData(fsBLOBFile.Length() - 1) As Byte
            fsBLOBFile.Read(bytBLOBData, 0, bytBLOBData.Length)
            fsBLOBFile.Close()
            Dim prm As New SqlParameter("@BLOBData", SqlDbType.VarBinary, _
                bytBLOBData.Length, ParameterDirection.Input, False, _
                0, 0, Nothing, DataRowVersion.Current, bytBLOBData)
            cmd.Parameters.Add(prm)
            cn.Open()
            cmd.ExecuteNonQuery()
            cn.Close()
                            

    This code uses a FileStream object to read the image file from disk to a Byte array and then uses a parameterized Command object to insert the data in the database.

  7. Add the following code in the Click event procedure of Button2:

            Dim cn As New SqlConnection(strCn)
            Dim cmd As New SqlCommand("SELECT BLOBID, " & _
                "BLOBData FROM BLOBTest ORDER BY BLOBID", cn)
            Dim da As New SqlDataAdapter(cmd)
            Dim ds As New DataSet()
            da.Fill(ds, "BLOBTest")
            Dim c As Integer = ds.Tables("BLOBTest").Rows.Count
            If c > 0 Then
                Dim bytBLOBData() As Byte = _
                    ds.Tables("BLOBTest").Rows(c - 1)("BLOBData")
                Dim stmBLOBData As New MemoryStream(bytBLOBData)
                picBLOB.Image = Image.FromStream(stmBLOBData)
            End If
                            

    This code retrieves the rows from the BLOBTest table in the database into a DataSet object, copies the image that is most recently added into a Byte array and then into a MemoryStream object, and then loads the MemoryStream into the Image property of the PictureBox control.

  8. Run the project.
  9. Click File to Database to load at least one sample image into the database.
  10. Click Database to PictureBox to display the image that you saved in the PictureBox control.
  11. To retrieve the image in a DataReader object instead of a DataSet object, modify the code in the Click event procedure of Button2 as follows:

            Dim cn As New SqlConnection(strCn)
            Dim cmd As New SqlCommand("SELECT BLOBID, " & _
                "BLOBData FROM BLOBTest ORDER BY BLOBID", cn)
            Dim dr As SqlDataReader
            cn.Open()
            dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
            If dr.Read Then
                Dim bytBLOBData(dr.GetBytes(1, 0, Nothing, 0, Integer.MaxValue) - 1) As Byte
                dr.GetBytes(1, 0, bytBLOBData, 0, bytBLOBData.Length)
                Dim stmBLOBData As New MemoryStream(bytBLOBData)
                picBLOB.Image = Image.FromStream(stmBLOBData)
            End If
            dr.Close()
                        
  12. To insert the image from the PictureBox control directly into the database, add a third Button control (Button3) to your form. Set the Text property of Button3 to PictureBox to Database, and then add the following code in the Click event procedure of Button3:

            Dim cn As New SqlConnection(strCn)
            Dim cmd As New SqlCommand("INSERT INTO BLOBTest (BLOBData) " & _
                "VALUES (@BLOBData)", cn)
            Dim ms As MemoryStream = New MemoryStream()
            picBLOB.Image.Save(ms, ImageFormat.Jpeg)
            Dim bytBLOBData(ms.Length - 1) As Byte
            ms.Position = 0
            ms.Read(bytBLOBData, 0, ms.Length)
            Dim prm As New SqlParameter("@BLOBData", SqlDbType.VarBinary, _
                bytBLOBData.Length, ParameterDirection.Input, False, _
                0, 0, Nothing, DataRowVersion.Current, bytBLOBData)
            cmd.Parameters.Add(prm)
            cn.Open()
            cmd.ExecuteNonQuery()
            cn.Close()
                            

    This code retrieves the image data from the PictureBox control in a MemoryStream object, copies the MemoryStream into a Byte array, and then uses a parameterized Command object to save the Byte array to the database.

  13. Run the project. Click Database to PictureBox to display an image that you previously saved in the PictureBox control.
  14. Click PictureBox to Database to save the image from the PictureBox to the database, and then click Database to PictureBox again to confirm that the image is saved correctly.

back to the top

Troubleshooting

  • This test does not work with the Photo column in the Employees table of the sample Northwind database that is included with Access and SQL Server. The bitmap images that are stored in the Photo column are wrapped with the header information that the Visual Basic 6.0 OLE Container control creates.
  • To use an Access database to test this code, you must create the column in the Access table as type OLE Object and then use the System.Data.OleDb namespace with the Microsoft Jet 4.0 Provider instead of the System.Data.SqlClient namespace.
  • You consume a lot of memory overhead if you retrieve all of the images from a table into your DataSet. To consume less overhead, leave the images in your database, and retrieve them one at a time as you move through your DataSet. To do this, execute a parameterized query to retrieve the image that you want into a DataReader, and then load the image from the DataReader into the PictureBox.

back to the top

REFERENCES

For additional information about how to use BLOB data with Visual Basic .NET, click the article numbers below to view the articles in the Microsoft Knowledge Base:

308042 How To Read and Write BLOB Data by Using ADO.NET with Visual Basic .NET


316887 How To Read and Write a File to and from a BLOB Column by Using ADO.NET and Visual Basic .NET


back to the top

Keywords: kbhowtomaster kbsqlclient kbsystemdata KB321900