"System.Drawing.Image" cannot be converted to '1-dimensional array - vb.net

I'm making a registration form with a picture in VB.Net using an Access database. Utilizing the following code, I am getting an error.
Me.Student_instructorTableAdapter.Insert(txtname,txtpass, ***PictureBox1.Image***)
Me.Student_instructorTableAdapter.Fill(Me.DatabaseDataSet4.student_instructor)
MsgBox("Successfully added", MsgBoxStyle.Information)
The PictureBox1.Image is saving into an Access Database ("picture") which throws an error:
"System.Drawing.Image" cannot be converted to '1-dimensional array"
What should I use instead of PictureBox1.Image when I call Insert in order to avoid the exception?

(Should be a comment but I need to post code)
We need the full exception message to know exactly what it's expecting (1-dimensional array of what?) Most likely it's a Byte array.
If so, you can convert an image to a Byte array like this...
Public Function ImageToByteArray(imageIn As System.Drawing.Image) As Byte()
Dim ms As New MemoryStream()
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Png)
Return ms.ToArray()
End Function
You can convert a Byte array back to an image like this...
Public Function byteArrayToImage(byteArrayIn As Byte()) As Image
Dim ms As New MemoryStream(byteArrayIn)
Dim returnImage As Image = Image.FromStream(ms)
Return returnImage
End Function
See here for more information
I'm not familiar with access data types so it may support images directly. If so, you need to make sure that you've got the right data type selected for that column/field.
Incidentally, if you don't have to, don't use Access (or at least the storage engine/JET) for new projects - it's slow, unreliable with more than 10 users and has serious security issues. If you don't want a full-up SQL Server database, consider SQL Compact Edition (CE) or SQL Express.

Related

Save local file from MS SQL varbinary

I'm trying to save a local document stored in SQL db using UiPath.
From the execute query activity it returns a DataTable value with one column(“Data”).
If I'm not wrong somehow I need to transform the DataTable.rows(0)(“Data”) (studio is interpreting it as object) to an array of bytes.
I used invoke code but the file is broken:
Dim _MemoryStream As New System.IO.MemoryStream()
Dim _BinaryFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
_BinaryFormatter.Serialize(_MemoryStream, inputObj)
_MemoryStream.ToArray()
File.WriteAllBytes(“C:\Users\Desktop\test.tiff”, _MemoryStream.ToArray())
Unless you serialised an object when saving, which I doubt, there's no reason to try to deserialise an object when retrieving. Every field from a DataRow is returned as an Object reference, because it must support any type of object, but that object still has its own type. If you saved binary data then that type will be Byte(), i.e. a Byte array. Kinda looks like File.WriteAllBytes takes a Byte array:
File.WriteAllBytes(“C:\Users\Desktop\test.tiff”, DirectCast(inputObj, Byte()))
That is what I would expect that you need to do. It does depend on how you saved the data in the first place but if you used File.ReadAllBytes or Image.Save then this should do the job. If not, show us how you sabed the data in the first place.

Buffer cannot be null

I try to download files from gridview .. I save files in database and then I display in grid-view I try this
I save files in database table not in folder so I try to download files
when i do this document is download but there is problem when i debug the code and check then in this line
Dim row = db_stu.dResult.Tables(0).Rows(i)
dResult shows
docid document docname docextension
1014 System.Byte[] Book2.xlsx .xlsx
and then when i further proceed docname shows "1912218726836.xlsx" this and also file download as a corrupt
These two lines together are wrong:
Dim binary() As Byte = TryCast(structDb.dstResult.Tables(0).Rows(i).Item("document"), Byte())
Dim ms As MemoryStream = New MemoryStream(binary)
The reason to use TryCast is that the object that you're trying to cast may not be the type you're trying to cast it as. In that case, TryCast will return Nothing. Use of TryCast should ALWAYS be followed by a test for Nothing, which you haven't done. You're using the result as though you're sure that there will be an object of that type. If you know that then you should be using DirectCast rather than TryCast.
Even if you do know that the reference will not be to an object of a different type and you use DirectCast though, if you cast a null reference, i.e. Nothing, then you're still going to get Nothing back. So, you first need to determine whether structDb.dstResult.Tables(0).Rows(i).Item("document") can refer to an object of a type other than Byte(). If it can't then use DirectCast rather than TryCast. Either way, it appears that that expression can produce Nothing so you need to check for Nothing either way, e.g.
Dim binary() As Byte = TryCast(structDb.dstResult.Tables(0).Rows(i).Item("document"), Byte())
If binary IsNot Nothing Then
Dim ms As MemoryStream = New MemoryStream(binary)
'...
End If
EDIT: If the column is nullable then you need to first test whether the row contains null and then only use the data if there is some:
Dim row = structDb.dstResult.Tables(0).Rows(i)
If Not row.IsNull("document") Then
'There is data so go ahead and use it.
Dim binary = DirectCast(row("document"), Byte())
'...

How to convert an iTextSharp.Image to vb .net MemoryStream

I'm having a little trouble with the iTexSharp library for .Net.
I want to generate a QR code and show the resulting image in a web page (or save it into a file, or wathever). Problem is, the class BarcodeQRCode only has the method GetImage() wich returns an iTextShrap.text.image object. From there I've tried to use the RawData property to create a Memory Stream, and that Memory Stream to create a Bitmap, but i get the Invalid Parameter Error. This is the code
1 Dim oQR As New BarcodeQRCode("DATA TO BE ENCODED", 1, 1, Nothing)
2 Dim oMS As New MemoryStream(oQR.GetImage().RawData)
3 Dim oBitmap As New Bitmap(oMS)
4 oBitmap.Save("C:\Users\MyUser\Documents\codigoQR.png", System.Drawing.Imaging.ImageFormat.Png)
(Error in line 3)
So there seems to be a problem with the Byte Array RawData is returning. Does anyone know the correct way to do what i'm trying, or if I'm missing something?

How to store Image Data in SQL VARCHAR(MAX) without a SQLCommand object

I've Googled the underlying question of how to store an image in the database and found many examples. However, all of the answers I'm seeing (for example this), seem to use a SQLCommand as the solution whether they are using the older "image" type, text, or suggesting VARCHAR(MAX). I am using SQL 2008 and SQL 2012
I'm having trouble incorporating this into my app since I have a legacy dll which will do some other work, and then store my image. I want to wrap this into a SQL transaction. The challenge is that the DLL is essentially a black-box to me since I cannot change the source code. The Dll exposes a parameter for an optional SQL statement it can run as part of its transaction.
The structure of the DLL is something like this:
Public Class MyClass
Public Property ExtraSQL as string
Public Function DoWork
Dim sMainSQL as String
'Start A transaction
Execute(sMainSQL)
If ExtraSQL <> "" Then
Execute(ExtraSQL)
End If
If OK Then Commit Transaction
End Function
End Class
My goal is to feed a SQL string into property ExtraSQL, but I'm not sure how to do this as all the examples are indicating something SqlCommand.Parameters(#Image).Value = byteArray(). I'm getting the image data from a web service. Over its life cycle, it's formatted as an Image, a base64 Encoded string, a memorystream and a byte array, so converting between the types is not the problem. I'm just unclear on the cleanest syntax for doing this. Is it best to just take my original base64 string and do something like:
INSERT INTO tblImage (ImageData) Values ('Base64 blah blah')
and then whenever I read the image back out do this:
Public Function Base64ToImage(ByVal base64String As String) As System.Drawing.Image
Dim img As System.Drawing.Image = Nothing
Try
'Convert Base64 string to byte array
Dim btImage As Byte() = Convert.FromBase64String(base64String)
Dim ms As New IO.MemoryStream(btImage, 0, btImage.Length)
ms.Write(btImage, 0, btImage.Length)
img = System.Drawing.Image.FromStream(ms, True)
Catch ex As Exception
End Try
Return img
End Function
I would appreciate any supporting links, examples, and advice. Thank you in advance.
Well, considering you clearly can't send in parameterized SQL, yes that's the best approach. I sure don't like it because it's wide open to SQL injection. I would consider decompiling the assembly you're using and making it my own source code in the future.

Serialize/Deserialize two-dimensional array

For some reason my previous question was considered too vague. So let me be more specific.
I have a 2 dimensional array of type single.
I want to serialize it to save in an Access database.
The suggestion was to save it as a Memo field which is fine.
I want to later read the Memo field and deserialize it to retrieve the original array.
I have searched extensively on the web and here and can not find the answer. I believe I am serializing the array correctly but do not know how to deserialize it.
This code appears to work for serializing but I can not figure out how to deserialize:
Dim f As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim ms As New MemoryStream
f.Serialize(ms, arLHS)
Dim byArr As Byte() = ms.ToArray
I then save byArr to the Memo field.
Please provide sample code.
You can deserialize it via base64 converter:
Dim str_b64 As String = Convert.ToBase64String(byArr)
Dim ms2 As New MemoryStream(Convert.FromBase64String(str_b64))
Dim intArr2(,) As Int32 = f.Deserialize(ms2)
This may look somewhat awkward, but it works - tested in a console app in VS 2010.
Credit goes here. Through this link, you can also find the full version of the code to play with.
I changed the data type of the Access field from Memo to OLE Object and that seems to work. When I look at the data in Access it tells me the field is "Long binary data" and I was able to use the following code after reading the record from Access:
Dim f As New System.Runtime.Serialization.Formatters.BinaryFormatter
Dim byArr As Byte()
byArr = DirectCast(dtLHS.Rows(0).Item("LHS"), Byte())
Dim theArrayAsString As String = Convert.ToBase64String(byArr)
Dim ms2 As New MemoryStream(Convert.FromBase64String(theArrayAsString))
Dim newLHS(,) as single = f.Deserialize(ms2)
Is this correct?