Click here to Skip to main content
15,889,462 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
See more:
I have an Access Database linked with a VB project through a data source. In the database on one of the tables, I have an OLE Object field. I have saved pictures in .BMP format and .JPG format in this field. The problem I am encountering is loading this image into my application. This is what I would like to be able to do:

VB
ButtonMeal1.BackgroundImage = IPOSDBDataSet.Meals.Rows(0).Item(5)


Where Item(5) is the column of the row where the image is stored. However, I know that this does not work.

I have also tried this method:

VB
Dim ImageByteArray As Byte() = CType(IPOSDBDataSet.Meals.Rows(0).Item(5), Byte())
Dim ImageMemoryStream As MemoryStream = New IO.MemoryStream(ImageByteArray)
Dim MyImage As Image = Drawing.Image.FromStream(ImageMemoryStream)
PictureBox1.Image = MyImage


However, when I debug this, I get the error "Parameter is not valid". I have modified this multiple times, but without any good result.

I have also read stuff about a header being stored in the OLE Object field, and that it must be removed, but I have no idea how to do this! There are no clear answers on the internet regarding my issue. Ultimately, I would just like to be able to load an image into my program from a database, whatever way possible!

Please help!
Posted
Comments
Ron Beyer 16-Jun-13 8:21am    
The memory stream way should work, how are you STORING it in the database? It has to be a similiar fashion to how you retrieve it. What is the column type?
JOFA666 16-Jun-13 20:35pm    
As I have mentioned, the picture is being stored in an OLE Object field inside the database. That is the column type.
saguptamca 16-Jun-13 14:12pm    
Give complete Dataset to correct answer on this and datatypes details

1 solution

I bumped into the OLE image format when using the Northwind.sdf file. The strange thing is that the DataGridView Image column can handle this data, but the Image Class can not.

I modified the code from this article (http://blogs.msdn.com/b/pranab/archive/2008/07/15/removing-ole-header-from-images-stored-in-ms-access-db-as-ole-object.aspx[^]) into a function to strip out the OLE data from a byte array.

Modify this line of your code to use the function.

Dim ImageMemoryStream As MemoryStream = New IO.MemoryStream(GetImageBytesFromOLEField(ImageByteArray))

VB
Friend Shared Function GetImageBytesFromOLEField(ByVal oleFieldBytes() As Byte) As Byte()

   Dim BITMAP_ID_BLOCK As String = "BM"
   Dim JPG_ID_BLOCK As String = ChrW(&HFF).ToString() & ChrW(&HD8).ToString() & ChrW(&HFF).ToString()
   Dim PNG_ID_BLOCK As String = ChrW(&H89).ToString() & "PNG" & vbCrLf & ChrW(&H1A).ToString() & vbLf
   Dim GIF_ID_BLOCK As String = "GIF8"
   Dim TIFF_ID_BLOCK As String = "II*" & ChrW(&H0).ToString()

   Dim imageBytes() As Byte

   ' Get a UTF7 Encoded string version
   Dim u7 As System.Text.Encoding = System.Text.Encoding.UTF7
   Dim strTemp As String = u7.GetString(oleFieldBytes)
   Dim st2 As String = System.Text.Encoding.UTF8.GetString(oleFieldBytes)
   ' Get the first 300 characters from the string
   Dim strVTemp As String = strTemp.Substring(0, 300)

   ' Search for the block
   Dim iPos As Integer = -1
   If strVTemp.IndexOf(BITMAP_ID_BLOCK) <> -1 Then
      iPos = strVTemp.IndexOf(BITMAP_ID_BLOCK)
   ElseIf strVTemp.IndexOf(JPG_ID_BLOCK) <> -1 Then
      iPos = strVTemp.IndexOf(JPG_ID_BLOCK)
   ElseIf strVTemp.IndexOf(PNG_ID_BLOCK) <> -1 Then
      iPos = strVTemp.IndexOf(PNG_ID_BLOCK)
   ElseIf strVTemp.IndexOf(GIF_ID_BLOCK) <> -1 Then
      iPos = strVTemp.IndexOf(GIF_ID_BLOCK)
   ElseIf strVTemp.IndexOf(TIFF_ID_BLOCK) <> -1 Then
      iPos = strVTemp.IndexOf(TIFF_ID_BLOCK)
   Else
      Throw New Exception("Unable to determine header size for the OLE Object")
   End If


   ' From the position above get the new image
   If iPos = -1 Then
   Throw New Exception("Unable to determine header size for the OLE Object")
   End If

   imageBytes = New Byte(CInt(oleFieldBytes.LongLength - iPos - 1)) {}
   Array.ConstrainedCopy(oleFieldBytes, iPos, imageBytes, 0, oleFieldBytes.Length - iPos)

   Return imageBytes

End Function
 
Share this answer
 
Comments
JOFA666 17-Jun-13 8:48am    
THANK YOU SO MUCH!!! This is the answer I have been looking for! I saw the article that you got the code from, but I have no idea on how to convert it to vb.net. Hopefully, this helps other people who are also trying to do the same thing. YOU ARE A LEGEND!!! THANKS FOR MAKING MY LIFE SO MUCH EASIER!!!!
Member 7856639 21-Mar-15 11:58am    
I am in a similar boat to JOFA666. I have an application with an Access client storing data in a SQL database. I am trying to include the images in an SSRS report and the OLE Header that Access wraps the image in causing SSRS to not recognize the image.

I tried adapting it to VB.NET code in the report and making the Image field an Expression: =Code.GetImageBytesFromOLEField(Fields!SIGNATURE.Value)

It compiles OK, and the report runs OK.. but the image field is blank. I am not a VB.NET programmer.. I am more of a SQL Server guy. Can someone help me?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900