Reputation: 185
when i try to capture an image to my webcam in VB.NET using Emgu and copy it into another PictureBox in another Form with this code Form23.PictureBox1.Image = New Bitmap(captureImageBox.Image)
and try to save it in my database, it doesn't save and an error appears like this Empty path name is not legal
but the picture is there and copied from the webcam PictureBox.
this is my code in saving the image in database:
Dim a As OpenFileDialog = New OpenFileDialog
SQL = "UPDATE candidate SET photo='" photo=@photo WHERE idn='" & cd & "'"
Dim sqlCommand As New MySqlCommand
sqlCommand.Parameters.Add("@photo", MySqlDbType.LongBlob)
sqlCommand.Parameters("@photo").Value = IO.File.ReadAllBytes(a.FileName)
With sqlCommand
.CommandText = SQL
.Connection = sConnection
.ExecuteNonQuery()
but if i save an image from OpenFileDialog
it saves. why can't it be?hmm
is there a problem in my code in copying the Image from PictureBox to another?
UPDATE
tried this but it doesn't work either:
Replaced this:
sqlCommand.Parameters.Add("@photo", MySqlDbType.LongBlob)
sqlCommand.Parameters("@photo").Value = IO.File.ReadAllBytes(a.FileName)
With sqlCommand
.CommandText = SQL
.Connection = sConnection
.ExecuteNonQuery()
with this one:
Dim ms As New IO.MemoryStream()
PictureBox1.Image.Save(ms, PictureBox1.Image.RawFormat)
Dim data As Byte() = MS.GetBuffer()
Dim p As New MySqlParameter("@photo", MySqlDbType.LongBlob)
p.Value = data
cmd.Parameters.Add(p)
sqlCommand.Parameters.Add("@cd", MySqlDbType.Int32).Value = cd
cmd.ExecuteNonQuery()
Upvotes: 1
Views: 17759
Reputation: 38905
Caveat: I have no idea what role the FileDialog plays in all this. Saving an image from a PictureBox to a database does not involve a File or a FileDialog. This address the Title question, not the updates where files and dialogs creep in.
First, consider not storing an image, but the name of an archived copy of the filename. You can mangle these as in <id>_<orgfilename>.<ext>
if you want to embed the ID to the disk file.
To save a picturebox image, it needs to be converted to as byte array. Net includes a type converter for that:
Dim imgData As Byte() ' storage for the img bytes
Dim cvt As New ImageConverter
imgData = CType(cvt.ConvertTo(myImage, GetType(Byte())), Byte())
It works (usually), but it also does boxing back and forth from Object (the CType) and issues with the ImageFormat it selects bug me. Doing it yourself is very simple:
' this is easily used from a class or converted to an extension
Public Shared Function ImgToByteArray(img As Image, imgFormat As ImageFormat) As Byte()
Dim tmpData As Byte()
Using ms As New MemoryStream()
img.Save(ms, imgFormat)
tmpData = ms.ToArray
End Using ' dispose of memstream
Return tmpData
End Function
This is pretty much what the TypeConverter does without the boxing, but the code controls the format. Then save the byte array to the db:
Dim imgData As Byte() ' storage for the img bytes
imgData = ImgToByteArray(PictureBox1.Image, ImageFormat.Jpeg)
...
sqlCommand.Parameters("@photo").Value = imgData
If you want a more generic procedure to save from file or picturebox, create a procedure which accepts a byte array as a param. The button click for Save PictureBoxImage can convert the image to byte array and pass it, as can the other button working from a file:
Function SaveRecord(ingData As Byte(),...other params...) As Boolean
Note: Do not use GetBuffer. See MSDN MemoryStream.GetBuffer:
Note that the buffer contains allocated bytes which might be unused. For example, if the string "test" is written into the MemoryStream object, the length of the buffer returned from GetBuffer is 256, not 4, with 252 bytes unused. ...
On a 968,012 byte file, .ToArray
returns the proper size, GetBuffer
returns 1,719,296 with all elements after 968012 being Null.
With just a little work you can create a class of image helpers:
Public Class myImaging
' image to byte array from file name
Public Shared Function ImgToByteArray(imgFile As String,
imgFormat As ImageFormat) As Byte()
...
' the one above
Public Shared Function ImgToByteArray(img As Image,
imgFormat As ImageFormat) As Byte()
...
' going the other way Bytes() --> Image
Public Shared Function ImgFromByteArray(b As Byte()) As Image
...
' shrink img and scale it
Public Shared Function ImgToThumb(img As Image, maxSize As Size) As Image
End Class
Then it is just: imgData = myImaging.ImgToByteArray(picturebox84.Image)
Upvotes: 3
Reputation: 185
got the answer!
Dim cn As New MySqlConnection("server = localhost; user id = root; database = db; password = root")
Dim sqlQuery As String = "UPDATE candidate SET cpos=@cpos, cparty=@cparty, candidacy='Filed', photo=@photo WHERE idn=@cd"
Dim sqlcom As New MySqlCommand(sqlQuery, cn)
Dim ms As New IO.MemoryStream()
PictureBox1.Image.Save(ms, Imaging.ImageFormat.Jpeg)
Dim data As Byte() = ms.GetBuffer()
Dim p As New MySqlParameter("@photo", MySqlDbType.LongBlob)
p.Value = data
sqlcom.Parameters.Add(p)
sqlcom.Parameters.AddWithValue("@cpos", ComboBox1.Text)
sqlcom.Parameters.AddWithValue("@cparty", TextBox1.Text)
sqlcom.Parameters.Add("@cd", MySqlDbType.Int32).Value = cd
cn.Open()
sqlcom.ExecuteNonQuery()
Upvotes: 0
Reputation: 416131
Dim a As OpenFileDialog = New OpenFileDialog
'...
SQL = "UPDATE candidate SET photo= @photo WHERE idn= @cd"
Dim sqlCommand As New MySqlCommand(SQL, sConnection)
sqlCommand.Parameters.Add("@photo", MySqlDbType.LongBlob).Value = IO.File.ReadAllBytes(a.FileName)
sqlCommand.Parameters.Add("@cd", MySqlDbtype.Int32).Value = cd
sConnection.Open()
sqlCommand.ExecuteNonQuery()
Upvotes: 0