将图片存储到数据库; 从数据库检索到Picturebox

您好我张贴这个较早,得到一些帮助,但仍然没有工作的解决scheme。 我已经确定感谢最后一个问题,我的“保存到数据库”代码以及我的“检索到图片”代码有问题。 即使如果我手动将图片保存在数据库它stil不会retreive。 这是我从网上的3或4个例子一起修补的代码。 理想情况下,如果有人有一些已知的良好的代码,并可以指示我,这将是最好的。

Dim filename As String = txtName.Text + ".jpg" Dim FileSize As UInt32 Dim ImageStream As System.IO.MemoryStream ImageStream = New System.IO.MemoryStream PbPicture.Image.Save(ImageStream, System.Drawing.Imaging.ImageFormat.Jpeg) ReDim rawdata(CInt(ImageStream.Length - 1)) ImageStream.Position = 0 ImageStream.Read(rawdata, 0, CInt(ImageStream.Length)) FileSize = ImageStream.Length Dim query As String = ("insert into actors (actor_pic, filename, filesize) VALUES (?File, ?FileName, ?FileSize)") cmd = New MySqlCommand(query, conn) cmd.Parameters.AddWithValue("?FileName", filename) cmd.Parameters.AddWithValue("?FileSize", FileSize) cmd.Parameters.AddWithValue("?File", rawData) cmd.ExecuteNonQuery() MessageBox.Show("File Inserted into database successfully!", _ "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk) 

![在这里input图片描述] [1]

' * **使用下面的代码retieving到图片框:

  Private Sub GetPicture() 'This retrieves the pictures from a mysql DB and buffers the rawdata into a memorystream Dim FileSize As UInt32 Dim rawData() As Byte Dim conn As New MySqlConnection(connStr) conn.Open() conn.ChangeDatabase("psdb") Dim cmd As New MySqlCommand("SELECT actor_pic, filesize, filename FROM actors WHERE actor_name = ?autoid", conn) Cmd.Parameters.AddWithValue("?autoid", Actor1Box.Text) Reader = cmd.ExecuteReader Reader.Read() 'data is in memory FileSize = Reader.GetUInt32(Reader.GetOrdinal("filesize")) rawData = New Byte(FileSize) {} 'get the bytes and filesize Reader.GetBytes(Reader.GetOrdinal("actor_pic"), 0, rawData, 0, FileSize) Dim ad As New System.IO.MemoryStream(100000) ' Dim bm As New Bitmap ad.Write(rawData, 0, FileSize) Dim im As Image = Image.FromStream(ad) * "error occurs here" (see below) Actor1Pic.Image = im Reader.Close() conn.Close() conn.Dispose() ad.Dispose() 

好吧,既然得不到帮助,我就把这个问题解决了,最后终于搞定了。 这是我的工作代码。

保存到MySQL的图片框(pbPicture)

  Dim filename As String = txtName.Text + ".jpg" Dim FileSize As UInt32 conn.Close() Dim mstream As New System.IO.MemoryStream() PbPicture.Image.Save(mstream, System.Drawing.Imaging.ImageFormat.Jpeg) Dim arrImage() As Byte = mstream.GetBuffer() FileSize = mstream.Length Dim sqlcmd As New MySqlCommand Dim sql As String mstream.Close() sql = "insert into [your table] (picture, filename, filesize) VALUES(@File, @FileName, @FileSize)" Try conn.Open() With sqlcmd .CommandText = sql .Connection = conn .Parameters.AddWithValue("@FileName", filename) .Parameters.AddWithValue("@FileSize", FileSize) .Parameters.AddWithValue("@File", arrImage) .ExecuteNonQuery() End With Catch ex As Exception MsgBox(ex.Message) Finally conn.Close() End Try 

从MySQL数据库加载回到Picturebox

  Dim adapter As New MySqlDataAdapter adapter.SelectCommand = Cmd data = New DataTable adapter = New MySqlDataAdapter("select picture from [yourtable]", conn) 

注意!! 只能放置一个图片在图片框显然这个查询只能为您返回一个logging

  commandbuild = New MySqlCommandBuilder(adapter) adapter.Fill(data) Dim lb() As Byte = data.Rows(0).Item("picture") Dim lstr As New System.IO.MemoryStream(lb) PbPicture.Image = Image.FromStream(lstr) PbPicture.SizeMode = PictureBoxSizeMode.StretchImage lstr.Close() 

testing代码存储和检索使用MySQL和VB.NET的图像

 Public Class FMImage Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click If OpenFileDialog1.ShowDialog(Me) = Windows.Forms.DialogResult.OK Then TextBox1.Text = OpenFileDialog1.FileName Dim filename As String = TextBox1.Text Dim FileSize As UInt32 Dim Conn As MySql.Data.MySqlClient.MySqlConnection Conn = New MySql.Data.MySqlClient.MySqlConnection Try If Conn.State = ConnectionState.Open Then Conn.Close() Conn.ConnectionString = MySQLConnectionString Conn.Open() Catch ex As Exception MessageBox.Show(ex.ToString, "Connect") End Try Dim mstream As System.IO.MemoryStream = ConvertImageFiletoMemoryStream(filename) PbPicture.Image.Save(mstream, Drawing.Imaging.ImageFormat.Jpeg) Dim arrImage() As Byte = ConvertImageFiletoBytes(filename) FileSize = mstream.Length Dim sqlcmd As New MySql.Data.MySqlClient.MySqlCommand Dim sql As String mstream.Close() 'CREATE TABLE `actors` ( `actor_pic` longblob,`filesize` bigint(20) default NULL,`filename` varchar(150) default NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1; sql = "insert into actors (actor_pic, filesize, filename) VALUES(@File, @FileName, @FileSize)" Try With sqlcmd .CommandText = sql .Connection = Conn .Parameters.AddWithValue("@FileName", filename) .Parameters.AddWithValue("@FileSize", FileSize) .Parameters.AddWithValue("@File", arrImage) .ExecuteNonQuery() End With Catch ex As Exception MsgBox(ex.Message) End Try Dim adapter As New MySql.Data.MySqlClient.MySqlDataAdapter adapter.SelectCommand = New MySql.Data.MySqlClient.MySqlCommand("SELECT actor_pic, filesize, filename FROM actors", Conn) Dim Data As New DataTable 'adapter = New MySql.Data.MySqlClient.MySqlDataAdapter("select picture from [yourtable]", Conn) Dim commandbuild As New MySql.Data.MySqlClient.MySqlCommandBuilder(adapter) adapter.Fill(Data) MsgBox(Data.Rows.Count) Dim lb() As Byte = Data.Rows(Data.Rows.Count - 1).Item("actor_pic") Dim lstr As New System.IO.MemoryStream(lb) PbPicture.Image = Image.FromStream(lstr) PbPicture.SizeMode = PictureBoxSizeMode.StretchImage lstr.Close() End If End Sub Public Function ConvertImageFiletoBytes(ByVal ImageFilePath As String) As Byte() Dim _tempByte() As Byte = Nothing If String.IsNullOrEmpty(ImageFilePath) = True Then Throw New ArgumentNullException("Image File Name Cannot be Null or Empty", "ImageFilePath") Return Nothing End If Try Dim _fileInfo As New IO.FileInfo(ImageFilePath) Dim _NumBytes As Long = _fileInfo.Length Dim _FStream As New IO.FileStream(ImageFilePath, IO.FileMode.Open, IO.FileAccess.Read) Dim _BinaryReader As New IO.BinaryReader(_FStream) _tempByte = _BinaryReader.ReadBytes(Convert.ToInt32(_NumBytes)) _fileInfo = Nothing _NumBytes = 0 _FStream.Close() _FStream.Dispose() _BinaryReader.Close() Return _tempByte Catch ex As Exception Return Nothing End Try End Function Public Function ConvertBytesToMemoryStream(ByVal ImageData As Byte()) As IO.MemoryStream Try If IsNothing(ImageData) = True Then Return Nothing 'Throw New ArgumentNullException("Image Binary Data Cannot be Null or Empty", "ImageData") End If Return New System.IO.MemoryStream(ImageData) Catch ex As Exception Return Nothing End Try End Function Public Function ConvertImageFiletoMemoryStream(ByVal ImageFilePath As String) As IO.MemoryStream If String.IsNullOrEmpty(ImageFilePath) = True Then Return Nothing ' Throw New ArgumentNullException("Image File Name Cannot be Null or Empty", "ImageFilePath") End If Return ConvertBytesToMemoryStream(ConvertImageFiletoBytes(ImageFilePath)) End Function End Class 

被接受的和有争议的答案可能会起作用,但这并不理想,而且相当浪费:

  1. 如果要保存的图像位于磁盘上,则没有理由使用UI控件 MemoryStream将图像转换为字节数组。
  2. 该代码也似乎重用一个单一的全局连接对象; 这些应该创build和处置,而不是重复使用。
  3. 考虑将文件名保存到数据库,可能已经散列,图像保存到一个特殊的文件夹。 保存图像数据会使数据库膨胀并花费更长的时间进行转换。
  4. 最后, .GetBuffer()是相当不正确的:
    memstream缓冲区通常会包含未使用的,分配的字节。 对于一个25k的testing文件, ToArray()返回25434字节 – 正确的图像大小 – 而GetBuffer()返回44416.图像越大,将会有更多的空字节。

这使用MySQL提供程序对象,因为它是如此标记的,但使用的数据提供程序(MySQL,SQLServer,OleDB等)并不重要:它们都工作相同。

在图像源是PictureBox的情况下,使用MemoryStream

 Dim picBytes As Byte() Using ms As New MemoryStream() picBox1.Image.Save(ms, imgFormat) picBytes = ms.ToArray() ' NOT GetBuffer! End Using 

由于图像必须来自某个地方,如果它是一个文件,这是所有你需要的:

 picBytes = File.ReadAllBytes(filename) 

一旦你的图像为字节,保存:

 Dim SQL = "INSERT INTO <YOUR TBL NAME> (picture, filename, filesize) VALUES(@Pic, @FileName, @FileSize)" Using conn As New MySqlConnection(connstr) Using cmd As New MySqlCommand(SQL, conn) conn.Open() cmd.Parameters.Add("@Pic", MySqlDbType.Blob).Value = picBytes cmd.Parameters.Add("@FileName", MySqlDbType.String).Value = filename cmd.Parameters.Add("@FileSize", MySqlDbType.Int32).Value = FileSize cmd.ExecuteNonQuery() End Using End Using ' close and dispose of Connection and Command objects 

从数据库加载图像

 Dim imgData As Byte() '... open connection, set params etc Using rdr As MySqlDataReader = cmd.ExecuteReader If rdr.HasRows Then rdr.Read() imgData = TryCast(rdr.Item("Image"), Byte()) ' in case this record has no image If imgData IsNot Nothing Then ' ToDo: dispose of any previous Image ' create memstream from bytes Using ms As New MemoryStream(imgData) ' create image from stream, assign to PicBox picBox1.Image = CType(Image.FromStream(ms), Image) End Using End If End If End Using 

请注意, BitmapsImages必须被丢弃。 如果您在用户浏览数据库时反复创build新图像,则应用程序将会泄漏并最终崩溃。 如果你来回转换很多,你可以写一个帮助器或扩展方法将图像转换为字节,反之亦然。

DBConnectionDBCommand对象也需要处理。 Using块为我们做这个。

参考资料:

  • 重用或处理数据库连接? 示例GetConnection助手
  • 连接池
  • MemoryStream.GetBuffer()
  • 我们可以停止使用AddWithValue()