Hateusz Hateusz - 2 months ago 12
Vb.net Question

Error when save resize image to Database

Hi I'm trying to save resized image from Picturebox to database. I have this code:

Dim Obrazek As Image
If OpenFileDialog1.ShowDialog = DialogResult.OK Then

PictureBox1.Image = Image.FromFile(OpenFileDialog1.FileName)

'516, 387
Dim NewSize As New Size(773, 580)
ResizeImage = New Bitmap(PictureBox1.Image, NewSize)
PictureBox1.Image = ResizeImage
Obrazek = ResizeImage


End If



Dim ImageIDShop As String = "0000"
'Get Image Via Memory stream
Dim img As Image = Obrazek
Dim ms As New MemoryStream
img.Save(ms, img.RawFormat)
Dim buffer As Byte() = ms.GetBuffer

'Add SQL Parameters
SQL.AddParam("@ImageIDShop", ImageIDShop)
SQL.AddParam("@imageString", buffer)

SQL.QueryArcades("INSERT INTO [dbo].[ImageTable]
([ImageIDShop]
,[ImageString])
VALUES
(@ImageIDShop
,@imageString) ")

ResizeImage.Dispose()

MsgBox("Saved")


Both parts seperate work grand but together I have error:

An unhandled exception of type 'System.ArgumentNullException' occurred in System.Drawing.dll

Additional information: Value cannot be null.

in Line:

img.Save(ms, img.RawFormat)


I was try save resized image from Picture box on disk and then send it to database, but then I have different error. I can save file using saveopendialog but I cant using simple code:

ResizeImage.Save("ImageName.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)


It will be great if any one can tell me what I'm doing wrong.

Answer

You have a great deal going on on that little bit of code:

  1. Interact with the user to select an image(?) file
  2. Resize it (the code doesnt actually do this, but looks like it is supposed to)
  3. Convert the image to Byte()
  4. Save to database

I would perform each step via an individual method. You also have multiple variables referring the same thing: Obrazek, img, PictureBox1.Image and ResizeImage all refer to the same image object. If you want to show the original or resized image in a PictureBox you cannot also Dispose of it. You'll likely get a big red X in it.

' 1: get selected image form user
If OpenFileDialog1.ShowDialog <> DialogResult.OK Then Return

Dim imgData As Byte()
Using selectedImg As Image = Image.FromFile(OpenFileDialog1.FileName)

    Using imgThumb As New Bitmap(selectedImg.Width \ 2, selectedImg.Height \ 2),
         g = Graphics.FromImage(imgThumb)

        ' 2: create resized image
        g.DrawImage(selectedImg, 0, 0, imgThumb.Width, imgThumb.Height)
        ' cannot use a Disposed image
        'pBox.Image = imgThumb

        ' 3: convert to byte()
        Using ms As New MemoryStream()
            imgThumb.Save(ms, ImageFormat.Jpeg)
            ' Do NOT use getbuffer!
            imgData = ms.ToArray()
        End Using

    End Using
End Using

Dim ImageIDShop As String = "0000"

' 4: save to DB
Using dbCon As New MySqlConnection(MySQLConnStr),
    cmd As New MySqlCommand("INSERT INTO BlobDemo (itemName, itemType, imgData) VALUES (@p1, @p2, @p3)", dbCon)

    cmd.Parameters.Add("@p1", MySqlDbType.String).Value = ImageIDShop
    cmd.Parameters.Add("@p2", MySqlDbType.String).Value = "jpg"
    cmd.Parameters.Add("@p3", MySqlDbType.Blob).Value = imgData

    dbCon.Open()
    cmd.ExecuteNonQuery()
End Using

Notes

  • This creates a resized image half the width and height of the original. You might want to check if the original even needs to be resized
  • The code implements using blocks to dispose of those things which should be disposed
  • If you want to retain either the original or the resized one, remove it from the Using block
  • Dont use GetBuffer() - as noted on MSDN it can result in a byte array much much larger than it needs to be and bloat the DB as a result.
  • You probably want to actually encode the resulting resized image rather than saving RawFormat
  • I have no idea what SQL.AddParam is - it looks like some sort of DB "helper". Given the params it almost have to be using AddWithValue with is not advised. There is not so much involved that it needs a helper.
Comments