Problem in saving image to database from picturebox. VB.Net 2008. Framework 3.5.
-
Hi there, I have a form containing a listbox showing a list of image names. It's bound to the database table. When an image name is clicked it shows the image and imagename in a picturebox and textbox respectively. When no image is selected in the listbox, a new record can be inserted by browsing a new image in the picturebox by an openfiledialog, writing the imagename in the textbox and pressing the OK button. When an image is already selected, the record can be updated by pressing the same OK button. The data is saved into MSSQL Server 2005. Corresponding table fields are Keycode int autono, logoname nvarchar(50), logo image. Now the problem, when I insert a new data with an image everything goes fine but whenever I try to update an existing data with an image it throws an exception- 'A generic error occurred in GDI+.' at the following line- 'pic.Image.Save(ms, pic.Image.RawFormat)'. Surprisingly when I update an existing data without any image in the picturebox no exception is generated. I have crossed checked it and seems that the problem is just at one point- 'Updating the image from the picturebox'. I'm almost done all throughout but stuck to this particular point. Please help. Regards. My code to insert/update the data by OK button and to populate it by listbox doubleclick follows:
Private ms As MemoryStream
Private arrImage() As Byte
Private conn As SqlConnection
Private cmd As SqlCommandPrivate Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Method to bind listbox.
BindListBox(lst, "Select Keycode,LogoName from tbltest", "Logoname", "keycode")
Tag = "Insert"
End SubPrivate Sub lst_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lst.DoubleClick
Dim dr As SqlDataReaderdr = CreateReader("Select LogoName,logo from tblTest where keycode=" & lst.SelectedValue) If dr.Read Then txtLogoName.Text = vbNullString & dr("Logoname") If Not IsDBNull(dr("Logo")) Then arrImage = CType(dr("Logo"), Byte()) ms = New MemoryStream(arrImage) pic.Image = Image.FromStream(ms) ms.Close() Else pic.Image = Nothing pic.Invalidate() End If Tag = "Update" End If dr.Close() closeconnection() arrImage = Nothing ms = Nothing
End Sub
Private Sub btnO
-
Hi there, I have a form containing a listbox showing a list of image names. It's bound to the database table. When an image name is clicked it shows the image and imagename in a picturebox and textbox respectively. When no image is selected in the listbox, a new record can be inserted by browsing a new image in the picturebox by an openfiledialog, writing the imagename in the textbox and pressing the OK button. When an image is already selected, the record can be updated by pressing the same OK button. The data is saved into MSSQL Server 2005. Corresponding table fields are Keycode int autono, logoname nvarchar(50), logo image. Now the problem, when I insert a new data with an image everything goes fine but whenever I try to update an existing data with an image it throws an exception- 'A generic error occurred in GDI+.' at the following line- 'pic.Image.Save(ms, pic.Image.RawFormat)'. Surprisingly when I update an existing data without any image in the picturebox no exception is generated. I have crossed checked it and seems that the problem is just at one point- 'Updating the image from the picturebox'. I'm almost done all throughout but stuck to this particular point. Please help. Regards. My code to insert/update the data by OK button and to populate it by listbox doubleclick follows:
Private ms As MemoryStream
Private arrImage() As Byte
Private conn As SqlConnection
Private cmd As SqlCommandPrivate Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Method to bind listbox.
BindListBox(lst, "Select Keycode,LogoName from tbltest", "Logoname", "keycode")
Tag = "Insert"
End SubPrivate Sub lst_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lst.DoubleClick
Dim dr As SqlDataReaderdr = CreateReader("Select LogoName,logo from tblTest where keycode=" & lst.SelectedValue) If dr.Read Then txtLogoName.Text = vbNullString & dr("Logoname") If Not IsDBNull(dr("Logo")) Then arrImage = CType(dr("Logo"), Byte()) ms = New MemoryStream(arrImage) pic.Image = Image.FromStream(ms) ms.Close() Else pic.Image = Nothing pic.Invalidate() End If Tag = "Update" End If dr.Close() closeconnection() arrImage = Nothing ms = Nothing
End Sub
Private Sub btnO
Hi, first of all, congrats on a great post. This is how it should be done! second, it is unfortunate however almost all problems inside GDI/GDI+ cause the same error message to appear and Image.Save() can fail for a whole lot of reasons (access denied, disk full, you name it). I didn't quite follow all the possible sequences of your logic, however this would be my best guess: - the file you want to save to is "in use"; - probably because you did open it for creating an Image object, either directly, as in Image.FromFile(); or indirectly as in new Stream(...) and Image.FromStream(). The file would be locked until the image object gets disposed of. - there isn't really a way to free the file while you still need the image, the Image class needs access to it in case you're going to manipulate the metadata. - my typical work-around is to never just do Image.FromFile(); instead I do:
Image temp=Image.FromFile(filepath)
Bitmap bm=new Bitmap(temp)
temp.Dispose()Disposing is what frees the file; using a "copy constructor" for a second image object breaks the connection between the remaining image and the original file. Hope this helps. BTW: your code is probably lacking some Dispose() calls anyway; pic.Image=Nothing is one way of potentially throwing away the last reference to an image without disposing it, causing it to linger around longer than necessary which isn't a good idea as images are rather large objects, and they often lock a file. :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.
-
Hi, first of all, congrats on a great post. This is how it should be done! second, it is unfortunate however almost all problems inside GDI/GDI+ cause the same error message to appear and Image.Save() can fail for a whole lot of reasons (access denied, disk full, you name it). I didn't quite follow all the possible sequences of your logic, however this would be my best guess: - the file you want to save to is "in use"; - probably because you did open it for creating an Image object, either directly, as in Image.FromFile(); or indirectly as in new Stream(...) and Image.FromStream(). The file would be locked until the image object gets disposed of. - there isn't really a way to free the file while you still need the image, the Image class needs access to it in case you're going to manipulate the metadata. - my typical work-around is to never just do Image.FromFile(); instead I do:
Image temp=Image.FromFile(filepath)
Bitmap bm=new Bitmap(temp)
temp.Dispose()Disposing is what frees the file; using a "copy constructor" for a second image object breaks the connection between the remaining image and the original file. Hope this helps. BTW: your code is probably lacking some Dispose() calls anyway; pic.Image=Nothing is one way of potentially throwing away the last reference to an image without disposing it, causing it to linger around longer than necessary which isn't a good idea as images are rather large objects, and they often lock a file. :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.
I have found the root of the problem but still couldn't get any solution. When we save the image using this line- 'pic.Image.Save(ms, pic.Image.RawFormat)' the image needs to be in its original format for the RawFormat() method to work properly. So when we click the Browse button, it's browsing an image into the picturebox in its original format. But when we retrieve the image from the database using arrays and streams, though we can view it but it's not in its original format and hence the above mentioned line in btnOk is throwing the exception. That's exactly the point and that's why inserting a new image is ok, update with a different image is ok but update with the same image is crashing. I think the key to solve it is while retrieving the image from the database if we can somehow convert it to its original format or some format that's recognizable by the RawFormat() method and then show it in the picturebox. In that way when we press btnOk for update, RawFormat() will get the original format of the picture and save it properly. I don't know how to do it practically or if there's some workaround. Can anybody make a solution out of this? Please assess on this topic and give your views. Regards.
-
I have found the root of the problem but still couldn't get any solution. When we save the image using this line- 'pic.Image.Save(ms, pic.Image.RawFormat)' the image needs to be in its original format for the RawFormat() method to work properly. So when we click the Browse button, it's browsing an image into the picturebox in its original format. But when we retrieve the image from the database using arrays and streams, though we can view it but it's not in its original format and hence the above mentioned line in btnOk is throwing the exception. That's exactly the point and that's why inserting a new image is ok, update with a different image is ok but update with the same image is crashing. I think the key to solve it is while retrieving the image from the database if we can somehow convert it to its original format or some format that's recognizable by the RawFormat() method and then show it in the picturebox. In that way when we press btnOk for update, RawFormat() will get the original format of the picture and save it properly. I don't know how to do it practically or if there's some workaround. Can anybody make a solution out of this? Please assess on this topic and give your views. Regards.
Why do you insist on using RawFormat at all? What people most often do when keeping an image in the database, is saving the image to a byte[], then the byte[] to a blob field; AND often also storing the filename so an appropriate file could be re-created. Maybe you should read a few CodeProject articles on the subject. :)
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.