将图像存储到数据库blob;从db检索到Picturebox

时间:2011-04-11 16:57:06

标签: mysql vb.net image blob picturebox

您好我之前发布的并获得了一些帮助,但仍然没有可行的解决方案。我已经确定感谢最后一次q&我的“保存到数据库”代码以及我的“检索到图片”代码有问题。即使我手动将图片保存在数据库中,它仍然不会撤消。这是我在网上围绕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)

![在此处输入图片说明] [1]

' * **使用以下代码返回到图片框:

  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()

5 个答案:

答案 0 :(得分:4)

好吧,自从得不到任何帮助后,我对这个问题感到震惊并终于开始工作了。这是我的工作代码。

从Picturebox中保存到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)

请注意!只能将一张图片放在图片框中,所以显然这个查询只能为你返回一条记录

    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()

答案 1 :(得分:2)

接受和赞成的答案可能有效,但它不是最理想且非常浪费:

  1. 如果要保存的图像位于磁盘上,则没有理由使用UI控件 MemoryStream将图像转换为字节数组。
  2. 代码似乎也重用了一个全局连接对象;这些应该被创造和处置而不是重复使用。
  3. 考虑将文件名保存到数据库,也许是哈希,将图像保存到特殊文件夹。保存图像数据会使数据库膨胀,转换时间也会更长。
  4. 最后,.GetBuffer()非常不正确:
    memstream缓冲区通常包括未使用的分配字节。使用25k测试文件,ToArray()返回25434字节 - 图像的正确大小 - 而GetBuffer()返回44416.图像越大,空字节越多。
  5. 这使用了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
    

    从DB

    加载图像
    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。如果您在用户浏览数据库时反复创建新图像,您的应用程序将泄漏并最终崩溃。如果你来回转换很多,你可以编写一个帮助器或扩展方法来将图像转换为字节,反之亦然。

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

    参考资料,资源:

答案 2 :(得分:0)

使用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

答案 3 :(得分:0)

我在使用mr @dMo程序时遇到问题,它向我显示错误“列'picture'不能为空”

here

这是我的代码。

Private Sub ButtonSave_Click(sender As Object, e As EventArgs) Handles ButtonSave.Click
    Dim filename As String = TextBoxSave.Text + ".jpg"
    Dim FileSize As UInt32

    conn.Close()

    Dim mstream As New System.IO.MemoryStream()
    PictureBoxSave.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 employeedetails  (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
End Sub

P.S。很抱歉发布这个帖子,我没有足够的声誉对此评论发表评论

答案 4 :(得分:0)

下面的代码将车辆信息记录插入表格中。所选汽车的图像将转换为内存流,并以Varbinary格式保存到数据库。

一个函数用于将图像转换为内存流。

  ' Upload new vehicle image

    Private Sub BtnUpload_Click(sender As Object, e As EventArgs) Handles 
    BtnUpload.Click

    Dim imgBinary As Byte()

    With Me.OpenFileDialog1
        .FileName = ""
        .Filter = "Image Files(*.BMP;*.JPG;*.JEPG;*.GIF)|*.BMP;*.JPG;*.JEPG;*.GIF|All files (*.*)|*.*"
        .RestoreDirectory = True
        .ValidateNames = True
        .CheckFileExists = True
        If .ShowDialog = Windows.Forms.DialogResult.OK Then
            'Me.PicImage.Image.Dispose()
            Me.PicImage.Image = System.Drawing.Image.FromFile(.FileName)
        End If
    End With

    imgBinary = ConvertImage(PicImage.Image)

    Dim command As New SqlCommand("insert into MyCars(CarId, Manufacture, CarModel, CarClass, CarImage) values(@CarId, @Manufacture, @CarModel, @CarClass, @CarImage)", connection)

    command.Parameters.Add("@CarId", SqlDbType.VarChar).Value = CInt(TxtID.Text)
    command.Parameters.Add("@Manufacture", SqlDbType.VarChar).Value = TxtManufacturer.Text
    command.Parameters.Add("@CarModel", SqlDbType.VarChar).Value = TxtModel.Text
    command.Parameters.Add("@CarClass", SqlDbType.VarChar).Value = TxtClass.Text
    command.Parameters.Add("@CarImage", SqlDbType.VarBinary).Value = imgBinary

    Try
        connection.Open()
        If command.ExecuteNonQuery() = 1 Then
            MessageBox.Show("Car # " & TxtID.Text & " successfully added to database.")
        Else
            MessageBox.Show("Car not added!")
        End If

    Catch ex As Exception
        MessageBox.Show("Error while inserting record on table..." & ex.Message, "Insert Records")
    Finally
        connection.Close()
    End Try

End Sub

以下功能将图像转换为内存流。

' Convert Image from Memory Stream
Public Function ConvertImage(ByVal myImage As Image) As Byte()

    Dim mstream As New MemoryStream
    myImage.Save(mstream, System.Drawing.Imaging.ImageFormat.Jpeg)

    Dim myBytes(mstream.Length - 1) As Byte
    mstream.Position = 0

    mstream.Read(myBytes, 0, mstream.Length)

    Return myBytes

End Function

下面的代码用于显示数据库中的图像。使用ID(作为整数)显示图像。

    Private Sub BtnShowImg_Click(sender As Object, e As EventArgs) Handles BtnShowImg.Click

    Dim command As New SqlCommand("select * from MyCars where CarId = @CarId", connection)
    command.Parameters.Add("CarId", SqlDbType.VarChar).Value = TxtID.Text

    Dim table As New DataTable()
    Dim adapter As New SqlDataAdapter(command)

    adapter.Fill(table)

    If table.Rows.Count <= 0 Then

        MessageBox.Show("No Image for the Selected Id")

    Else

        TxtID.Text = table.Rows(0)(0).ToString()                ' Col 0 = CarId
        TxtManufacturer.Text = table.Rows(0)(1).ToString()      ' Col 1 = Manufacturer
        TxtModel.Text = table.Rows(0)(2).ToString               ' Col 2 = Model
        TxtClass.Text = table.Rows(0)(3).ToString()             ' Col 3 = Vehicle Class

        Dim img() As Byte
        img = table.Rows(0)(4)  ' Col 4 = Img

        Dim ms As New MemoryStream(img)

        PicImage.Image = Image.FromStream(ms)

    End If

End Sub

Interface - Hope It Helps