0

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:

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

Where Item(5) is the column of the row where the image is stored.

Is there another way of doing this. Do I have to load the picture into the program by storing it as a variable, and then using that to change the background image of the button. There are no clear answers on the internet regarding my issue. Please help!

EDIT 1: After doing some more research, I found some code and adjusted it to try fix my problem.

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, I receive the error "Parameter is Not Valid" with the 3rd line of the code. Would anyone be able to tell me how I could adjust my code to fix this issue, or tell me if I am doing something completely wrong?

EDIT 2: I keep on changing the code around, but the error is always "Parameter is not valid.". What parameter is not valid?

EDIT 3: No matter what I change it to, the error still persists. What is this parameter that is causing all my issues?

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

EDIT 4: Can anyone please help? I really need to be able to implement this into my program. Is there any other possible way of storing images in an access database, and importing them into my vb.net program?

5
  • Why don't you just save the name of images in your DB ? Commented Jun 15, 2013 at 3:10
  • You need to get better at finding answers on the internet. :-) The problem is the "as OLE Object field", which means the OLE header information is being stored as well. See Removing OLE Header from images stored in MS Access DB as OLE Object Commented Jun 15, 2013 at 3:40
  • You might have to make it Dim MyImage as Image = Drawing.Image.FromStream((Stream)ImageMemoryStream) or however that is done in VB.NET. I'm not sure since I'm used to coding in C#, but you might have to explicitly convert the time to Stream. Commented Jun 15, 2013 at 5:03
  • Still doesn't like the code. Any other suggestions? Commented Jun 15, 2013 at 5:12
  • ImageMemoryStream is a MemoryStream object. You may need to coerce it or copy it to a Stream object. Commented Jun 15, 2013 at 5:20

3 Answers 3

1

Credit goes to TnTinMan from CodeProject for the answer. Hopefully this helps someone else:

Dim ImageByteArray As Byte() = CType(DataSet.Table.Rows(RowNo).Item(ItemNo), Byte())
Dim ImageMemoryStream As MemoryStream = New IO.MemoryStream(GetImageBytesFromOLEField(ImageByteArray))
Dim MyImage As Image = Drawing.Image.FromStream(ImageMemoryStream)


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
Sign up to request clarification or add additional context in comments.

Comments

0

There isn't really such a thing as an 'image' stored in an Access table, only a binary stream. Therefore, the left hand side of your expression doesn't know that the right hand side is providing an image. You would have to stream the binary stream into a stream in VB.NET, then use System.Graphics methods to make it into a BMP or PNG or whatever. You could assign that object to the button.

6 Comments

You would have to stream the binary stream into a stream in VB.NET, then use System.Graphics methods to make it into a BMP or PNG or whatever. You could assign that object to the button. I have never used binary streams or any other type of stream for that matter. Therefore, I am searching for answers but not understanding what it is that I should be doing. Could you show me an example of what I could do, or link me to a good example?
@Joshua: The link I provided in my comment to your question gives you that example. Did you even read it?
Yes. I did see your link, but it is not clear to me as to exactly what I should be doing. That is why I am asking if you would be able to show me an example?
Also, it looks like the example you gave me is in the language C#, not VB.NET.
Before you do anything else, get familiar with the System.Drawing library. Rather than focus on your problem, simply learn your way around that functionality. It will become clear at that point how you get to where you need to be.
|
0

still show error: index and length must refer to a location within the string.Parameter name: len

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.