Search code examples
mysqlvb.netpngjpegcorrupt

Inserting a PNG or JPG into MySQL is corrupting the image


I have a problem with inserting some JPG or PNG images into MySQL. Some of these images are corrupt.

Screenshot of corrupt JPG:

JPG Corrupt

Screenshot of corrupt PNG:

PNG Corrupt

What is wrong with my code?

Code:

Private Sub Button3_Click_1(sender As Object, e As EventArgs) Handles Button3.Click
    Dim cmd As New MySqlCommand
    Dim SQL As String
    Dim FileSize As UInt32
    Dim rawData() As Byte = IO.File.ReadAllBytes(ListBox1.SelectedItem)
    Dim fs As FileStream
    Try
        fs = New FileStream(ListBox1.SelectedItem.ToString, FileMode.Open, FileAccess.Read)
        FileSize = fs.Length
        rawData = New Byte(FileSize) {}
        fs.Read(rawData, 0, FileSize)
        'fs.Close()
        MysqlConn.Open()
        SQL = "INSERT INTO xcollectibles.foto (foto) VALUES(@foto)"
        cmd.Connection = MysqlConn
        cmd.CommandText = SQL
        cmd.Parameters.AddWithValue("@foto", rawData)
        cmd.ExecuteNonQuery()
        fs.Close()
        MessageBox.Show("File Inserted into database successfully!",
        "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
        MysqlConn.Close()
    Catch ex As Exception
        MessageBox.Show("There was an error: " & ex.Message, "Error",
                MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try
End Sub

I have also tried:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    MysqlConn.Open()
    Me.Cursor = Cursors.WaitCursor
    For i = 0 To Me.ListBox1.Items.Count - 1
        ProgressBar1.Maximum = Me.ListBox1.Items.Count - 1
        Me.ListBox1.SetSelected(i, True)
        Dim cmd As New MySqlCommand
        Dim SQL As String
        Dim filesize As UInt32
        Dim mstream As New System.IO.MemoryStream()
        If TextBox1.Text = ".jpg" Then
            PictureBox1.Image.Save(mstream, Imaging.ImageFormat.Jpeg)

        ElseIf TextBox1.Text = ".png" Then
            PictureBox1.Image.Save(mstream, Imaging.ImageFormat.Png)

        ElseIf TextBox1.Text = ".bmp" Then
            PictureBox1.Image.Save(mstream, Imaging.ImageFormat.Png)

        End If


        'Dim bmp As New Bitmap(Width, Height)
        'Dim g As Graphics = Graphics.FromImage(bmp)
        'g.Clear(Color.Transparent)
        'bmp.Save(mstream, System.Drawing.Imaging.ImageFormat.Png)


        'End If
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        Dim arrImage() As Byte = mstream.GetBuffer()
        filesize = mstream.Length
        mstream.Close()
        SQL = "INSERT INTO xcollectibles.foto (id_product,foto) VALUES ((Select id from xcollectibles.product where product.name='" & ComboBox1.Text & "'), @foto) "
        ProgressBar1.Value = i
        cmd.Connection = MysqlConn
        cmd.CommandText = SQL
        cmd.Parameters.AddWithValue("@foto", arrImage)
        cmd.ExecuteNonQuery()
    Next
    MessageBox.Show("File Inserted into database successfully!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
    MysqlConn.Dispose()
    ProgressBar1.Value = 0
    Me.Cursor = Cursors.Default
End Sub

I try something different now.... Save the file in a path of the computer and save the path in mysql

I try this to add the file

System.IO.Directory.CreateDirectory("C:\Users\Jamyz\Source\Repos\xCollectibles\xCollectibles\xCollectibles\Images" & "\" & ComboBox1.Text)
        Dim SaveFile As New System.IO.StreamWriter("C:\Users\Jamyz\Source\Repos\xCollectibles\xCollectibles\xCollectibles\Images" & "\" & ComboBox1.Text & "\" & TextBox3.Text)

        If TextBox1.Text = ".jpg" Then
            PictureBox1.Image.Save("C:\Users\Jamyz\Source\Repos\xCollectibles\xCollectibles\xCollectibles\Images\mypic.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)
        ElseIf TextBox1.Text = ".bmp" Then
            PictureBox1.Image.Save("C:\Users\Jamyz\Source\Repos\xCollectibles\xCollectibles\xCollectibles\Images\mypic.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
        ElseIf TextBox1.Text = ".png" Then
            PictureBox1.Image.Save("C:\Users\Jamyz\Source\Repos\xCollectibles\xCollectibles\xCollectibles\Images\mypic.png", System.Drawing.Imaging.ImageFormat.Png)
        End If

But i want saving the file with the folder of

System.IO.Directory.CreateDirectory("C:\Users\Jamyz\Source\Repos\xCollectibles\xCollectibles\xCollectibles\Images" & "\" & ComboBox1.Text)

and save the file with the name of TextBox3.Text

Dim SaveFile As New System.IO.StreamWriter("C:\Users\Jamyz\Source\Repos\xCollectibles\xCollectibles\xCollectibles\Images" & "\" & ComboBox1.Text & "\" & TextBox3.Text)

Because with in the exemple of

PictureBox1.Image.Save("C:\Users\Jamyz\Source\Repos\xCollectibles\xCollectibles\xCollectibles\Images\mypic.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)

The file is overwrites ........

Thank you so much.......


Solution

  • You have to convert the image to a byte array before you can store it in a database. I use Oracle, but I imagine that Sql Server is the same. I capture the photo from a upload, scale the image to a thumbnail and then convert it to a byte array to store in the database. See code below:

        If Not file1.PostedFile Is Nothing And file1.PostedFile.ContentLength > 0 Then
            Session("ThePhoto") = ""
            Dim TheStream As Stream = file1.PostedFile.InputStream
            Dim origimage As System.Drawing.Image
            origimage = System.Drawing.Image.FromStream(TheStream)
    
            Dim ms2 As New System.IO.MemoryStream
            origimage = ScaleImage(origimage, 320, 200) ' Thumbnail
            origimage.Save(ms2, Imaging.ImageFormat.Jpeg)
            Dim MyPhoto() As Byte = ms2.GetBuffer ' The scaled image is now stored in memory as a byte array
            Session("ThePhoto") = MyPhoto ' put it into the session to retreive later
            ms2.Dispose()
            origimage.Dispose()
        End If
    

    I store the image in the session object because there are other things going on and I can't yet save the image to the database until the user clicks the save button. It's pretty straight forward to pass the byte array to a stored procedure to save to the database.