0

I have a column that stored picture in an MS Access database. In that column I right-click it and insert object which is picture from file and it said "package" in the column.

The idea is to upload picture to 'pic' column in access database from file, and using 'querypic' table adapter query with parameter is 'comboname.text' is selected to return picture and store it as binary in byte of array

but when i convert it to image i got an error

System.ArgumentException: 'Parameter is not valid.

I checked my b() which is array of byte and it got result {length=40276} can someone help me?

Private Sub cmdSelect_Click(sender As Object, e As EventArgs) Handles cmdSelect.Click
        Dim facultytabeladapt As New CSE_DEPTDataSetTableAdapters.FacultyTableAdapter
        Dim b() As Byte
        Dim s As String
        b = facultytabeladapt.querypic(ComboName.Text)

        PhotoBox.Image = b21(b)


    End Sub
    Private Function b21(ByVal b() As Byte) As Image

        Dim imgc As New ImageConverter

        Dim imgpic As Image = CType(imgc.ConvertFrom(b), Image) 'it has error "System.ArgumentException: 'Parameter is not valid."
        Return imgpic
    End Function

this probably because of the OLEDB object in pic that i upload directly to access and not RAW binary file

Edit: querypic is

SELECT        pic
FROM            Faculty
WHERE        (faculty_name = ?)

where faculty_name is comboname.text

fiksx
  • 176
  • 1
  • 15

1 Answers1

1

If you already have a byte array, create a memory stream from the byte array, then create an image from the stream. Don't forget to add Import System.IO to use MemoryStream class.

Private Function b21(ByVal b() As Byte) As Image

    Dim ms As New MemoryStream(b) ' create memory stream from byte array
    Return Image.FromStream(ms) ' create image from memory stream

End Function

Full code:

Imports System.IO
Imports System.Drawing.Imaging

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        Dim b() As Byte
        b = ReadImage(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) & "\test.png")
        PhotoBox.Image = b21(b)

    End Sub

    Private Function b21(ByVal b() As Byte) As Image

        Dim ms As New MemoryStream(b) ' create memory stream from byte array
        Return Image.FromStream(ms) ' create image from memory stream

    End Function

    ''' <summary>
    ''' This function reads a file and returns a byte array
    ''' </summary>
    ''' <param name="file">A file in full path name</param>
    ''' <returns>A byte array of the image</returns>
    Private Function ReadImage(file As String) As Byte()

        Dim image As Image = Image.FromFile(file) ' read image from file
        Dim ms As New MemoryStream ' prepare a memory stream
        image.Save(ms, ImageFormat.Png) ' save the image into memory stream
        Return ms.ToArray() ' return byte array

    End Function

End Class
Han
  • 3,052
  • 2
  • 22
  • 31
  • It belongs to the .Net Framework so you can use it with C# and VB.Net. Just add `Imports System.IO` at the top of your code. – Han Sep 07 '18 at 13:50
  • thanks but still the same, in "Return Image.FromStream(ms) ' create image from memory stream" , i got error "System.ArgumentException: 'Parameter is not valid.", i searched about this and it seems because of ole db object that i upload picture directly to access so it is not RAW binary , is there anyway to solve this? "https://stackoverflow.com/questions/16453792/emgucv-face-recognition-object-reference-not-set-exception-when-using-trai/16462624#16462624" – fiksx Sep 07 '18 at 14:00
  • Are you sure that b() is a byte array of the picture? Post the facultytabeladapt.querypic() method. And what is the value of ComboName.Text? – Han Sep 07 '18 at 14:03
  • b() is a byte array, but it is not RAW binary, im sorry i posted wrong link , please refer to this https://stackoverflow.com/questions/17351260/parameter-not-valid-error-in-vb-net-while-retrive-image-to-picturebox-from-ms , if i store picture not directly to access, the status in access collumn will be "long binary file" , but i store picture directly to access so the status is "package" and it is OLE object type so it is not RAW binary – fiksx Sep 07 '18 at 14:06
  • I'm having difficulties if you post only half of what is needed. I don't know how you store the image in the MS Access database. I also don't know how you read the image from the MS Access database. Please post more code. – Han Sep 07 '18 at 14:11
  • i added the querypic sql , but im sure it is because the OLEDB type which is not return RAW binary, so the parameter is wrong – fiksx Sep 07 '18 at 14:17
  • 1
    @Jimi - The OLE wrapper prefix can be a lot more than 154 bytes; see [this answer](https://stackoverflow.com/a/19709053/2144390) for an example. – Gord Thompson Sep 07 '18 at 15:39
  • 1
    @Gord Thompson Yep, you're right. It's a variable length, actually. The path + filename is stored. – Jimi Sep 07 '18 at 16:22
  • @Gord Thompson Inspecting the package header, also the path to the System Temp repository used for the transfer is stored. This gives some opportunities though. Extracting the file type (given the extension) - the path string uses the local Encoding - and detecting the end of the header, from which the actual data begins. Since it's a (sort of a) header, it will probably have it's length stored somewhere. (If you already know that, don't keep it for yourself :) – Jimi Sep 07 '18 at 16:35
  • This turns out much more complex than what I thought. Thanks for the information, Jimi & Gord Thompson. – Han Sep 07 '18 at 19:04
  • I think I've decoded the OLE Package structure, at least for an Embedded File. I could post the specs with some description and you could give it a test drive and see what comes out of it, then post some code. It could be interesting. The Package stores the file name (and original path), thus you can also know what kind of file you're dealing with beforehand. The actual file size is there. Maybe @Gord Thompson is interested, too. – Jimi Sep 07 '18 at 22:32