Some time ago I wanted to find out how to read image data stored in a database
BLOB column into Freeimage without having to save the BLOB as a temporary file
on disk first. It seemed pretty obvious that using FreeImage_OpenMemory was
the way to go but nobody else had been able to get any help with it here so I
gave up as I was short of time. I've now had time to revisit the issue and
thought it would be a good idea to to post some simple sample code to
demonstrate the process.
Dim rsWork As New cRecordset
Dim byBlobData() As Byte
Dim lngMem As Long
Dim fifMem As FREE_IMAGE_FORMAT
Dim fibImage As Long
cnnDB.OpenDB mstrDBFile
Set rsWork = cnnDB.OpenRecordset("SELECT Image_Len, ImageData FROM Medications")
byBlobData = rsWork.Fields("ImageData").value
' Note that we just pass in the the first item of the array as VB handles
' turning it into an appropriate pointer
lngMem = FreeImage_OpenMemory(byBlobData(0), rsWork!Image_Len)
fifMem = FreeImage_GetFileTypeFromMemory(lngMem)
fibImage = FreeImage_LoadFromMemory(fifMem, lngMem, 0)
FreeImage_PaintDC Me.hdc, fibImage
FreeImage_Unload fibImage
FreeImage_CloseMemory lngMem
Set rsWork = Nothing
End Sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
you could do this even more easily by using wrapper method
FreeImage_LoadFromMemoryEx, which takes a VB-style Byte array as its first
parameter. Have a look at this modified version of your code.
Dim rsWork As New cRecordset
Dim byBlobData() As Byte
Dim fifMem As FREE_IMAGE_FORMAT
Dim fibImage As Long
cnnDB.OpenDB mstrDBFile
Set rsWork = cnnDB.OpenRecordset("SELECT Image_Len, ImageData FROM Medications")
byBlobData = rsWork.Fields("ImageData").Value
' If you need the image type, add fifMem as the last ByRef parameter, which will contain the image's type
' after the function returns.
fibImage = FreeImage_LoadFromMemoryEx(byBlobData, , , fifMem)
' Use this line instead, if you do not need the image type.
'fibImage = FreeImage_LoadFromMemoryEx(byBlobData)
' Now, paint the image.
FreeImage_PaintDC Me.hDC, fibImage
' Unload the FreeImage bitmap from memory.
FreeImage_Unload fibImage
Set rsWork = Nothing
However, FreeImage_LoadFromMemoryEx only works with explicitly declared VB-
style arrays so, you always need to assign your recordset field's value to a
(Byte in this case) array. Although it seems obvious, doing this even shorter
like
Carsten,
I tried your code, but FreeImage_LoadFromMemoryEx returns 0
Running step by step through the code, I found out that FreeImage_GetFileTypeFromMemory(hStream) returns -1 (unknown) ?
Could you please help?
Here's what i did:
public function test()
dim rs as recordset
dim data() as byte
dim dib as long
' "bild" is the memo/blob field containing the binary data
set rs = currentdb().openrecordset("select * from tabelle1")
rs.edit
rs!bild = readbitmap("C:\temp\test.bmp")
rs.update
rs.Requery
' now we have the binaray data in the memo field
data = rs!bild
Public Function readbmp(pfad As String) As String
Dim content As String
Open pfad For Binary Access Read As #1
content = Space(LOF(1))
Get #1, , content
readbmp = content
Close #1
End Function
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
have you had a look at the data array after that line? Does is contain the same bytes that you see when you view the file C:\temp\test.bmp with a HEX editor?
Currently I'm on vacation (St. Peter Ording) and only have a Linux box with me, so I'm not really able to figure out things about VBA and Access. But I guess that something with loading /storing / requerying of the image file's
bytes goes wrong.
Maybe you should not load the image file into a String variable in function readbmp. Try it with a byte array. Make the function return Byte() and turn variable content into a byte array. Then use
ReDim content(LOF(1) - 1)
instead of the Space() function.
Carsten
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Some time ago I wanted to find out how to read image data stored in a database
BLOB column into Freeimage without having to save the BLOB as a temporary file
on disk first. It seemed pretty obvious that using FreeImage_OpenMemory was
the way to go but nobody else had been able to get any help with it here so I
gave up as I was short of time. I've now had time to revisit the issue and
thought it would be a good idea to to post some simple sample code to
demonstrate the process.
Hi Crunchy Frog,
you could do this even more easily by using wrapper method
FreeImage_LoadFromMemoryEx, which takes a VB-style Byte array as its first
parameter. Have a look at this modified version of your code.
However, FreeImage_LoadFromMemoryEx only works with explicitly declared VB-
style arrays so, you always need to assign your recordset field's value to a
(Byte in this case) array. Although it seems obvious, doing this even shorter
like
does not work.
Carsten
Thanks for the follow-up Carsten. I'll revisit my working code as you
recommend.
Regards
Steve Murphy
Carsten,
I tried your code, but FreeImage_LoadFromMemoryEx returns 0
Running step by step through the code, I found out that FreeImage_GetFileTypeFromMemory(hStream) returns -1 (unknown) ?
Could you please help?
Here's what i did:
Hi,
have you had a look at the data array after that line? Does is contain the same bytes that you see when you view the file C:\temp\test.bmp with a HEX editor?
Currently I'm on vacation (St. Peter Ording) and only have a Linux box with me, so I'm not really able to figure out things about VBA and Access. But I guess that something with loading /storing / requerying of the image file's
bytes goes wrong.
Maybe you should not load the image file into a String variable in function readbmp. Try it with a byte array. Make the function return Byte() and turn variable content into a byte array. Then use
ReDim content(LOF(1) - 1)
instead of the Space() function.
Carsten