Handling with dementia

N

Nak

Hi there,

I am having great fun with Pointers or Handlers or whatever you want to
call them in VB.NET. WHat I am attempting to do is create a .NET image by
using the FreeImage library. On the site they clear say,

------------------------

How do I convert a FreeImage image to a HBITMAP ?

FIBITMAP *dib = FreeImage_Load(FIF_PNG, "test.png", PNG_DEFAULT);
HBITMAP bitmap = CreateDIBitmap(hDC, FreeImage_GetInfoHeader(dib),
CBM_INIT, FreeImage_GetBits(dib), FreeImage_GetInfo(dib), DIB_RGB_COLORS);

------------------------

Now I know that this is C++, but I thought this shouldn't be hard to
convert, surely? So I have written the following function in replacement to
the above

------------------------

Private Function getFreeImage(ByVal iFileName As String) As Image
Try

'create a FreeImage Wrapper and get a handle to the desired image

Dim pFIWImage As New freeImage_Wrapper()
Dim pIntFIHandle As Integer =
pFIWImage.FreeImage_Load(freeImage_Wrapper.FreeImage_GetFileType(iFileName,
0), iFileName, 0)

'Create a new DC that we can use with the CreateDIBitmap API

Dim pBmpBitmap As Bitmap = New
Bitmap(Convert.ToInt32(pFIWImage.FreeImage_GetWidth(pIntFIHandle)),
Convert.ToInt32 (pFIWImage.FreeImage_GetHeight(pIntFIHandle)))
Dim pGraGraphics As Graphics = Graphics.FromImage(pBmpBitmap)
Dim pIPrHDC As IntPtr = pGraGraphics.GetHdc


'Convert the DIB to a DDB using the API CreateDIBitmap

Dim pBIHInfoHeader As BITMAPINFOHEADER =
pFIWImage.FreeImage_GetInfoHeader(pIntFIHandle)
Dim pIPrBits As IntPtr = pFIWImage.FreeImage_GetBits(pIntFIHandle)
Dim pBIoInfo As BITMAPINFO = pFIWImage.FreeImage_GetInfo(pIntFIHandle)
Dim pIntDDBHandle As Integer = CreateDIBitmap(pIPrHDC.ToInt32,
pBIHInfoHeader, CBM_INIT, pIPrBits, pBIoInfo, DIB_RGB_COLORS)

'Now we have a handle to a HBitmap we can create a .NET Image

Dim pImgImage As Image = Image.FromHbitmap(New IntPtr(pIntDDBHandle))

'Release the DC and unload the image

Call pGraGraphics.ReleaseHdc(pIPrHDC)
Call pFIWImage.FreeImage_Unload(pIntFIHandle)

'Return out image

Return (pImgImage)
Catch ex As Exception
MessageBox.Show(ex.ToString)
Return (Nothing)
End Try
End Function

------------------------

Now all I am getting out of this is 1 black pixel, no more, no less.
Why is this? I *think* it may have something to do with the way I am
passing the handle of the HBitmap to the FromHBitmap method, according the
MSDN a handle *is* returned by the API. Unfortunately seeing as my handle
is a 32 bit integer, I can't just pass it straight to the method, so I am
creating a new IntPtr object, which I *presume* creates a pointer to my
value, or doesn't it?

I must be so close to achieving what I want, yet this bit is confusing
me, if I display the value of "New IntPtr(pIntDDBHandle)" in a messagebox I
get the same value each time, so it can't be a pointer, can it? How the
hell can I do this? I have even tried using StretchDIBits to attempt to
blit the DIB onto my bitmap but still no luck :-(

Any help would be greatly appreciated, thanks loads in advance.


Nick.

--
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
"No matter. Whatever the outcome, you are changed."

Fergus - September 5th 2003
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
 
T

Tom Spink

Instead of getting pointers in Integers, you should recieve them in IntPtr's

You'll also need to change the parameters to IntPtr's, where appropriate.
Anything that's a handle, or a pointer, should be IntPtr.

Declare Function FreeImage_Load(...) As IntPtr
Declare Function CreateDIBitmap(...) As IntPtr

Dim phImage As IntPtr = CreateDIBitmap(...)

Dim imgImage As Image = Image.FromHBitmap(phImage)

--
HTH,
-- Tom Spink, Über Geek

Please respond to the newsgroup,
so all can benefit

" System.Reflection Master "

==== Converting to 2002 ====
Remove inline declarations
 
N

Nak

Hi Tom,
Instead of getting pointers in Integers, you should recieve them in IntPtr's

You'll also need to change the parameters to IntPtr's, where appropriate.
Anything that's a handle, or a pointer, should be IntPtr.

Declare Function FreeImage_Load(...) As IntPtr
Declare Function CreateDIBitmap(...) As IntPtr

Dim phImage As IntPtr = CreateDIBitmap(...)

Dim imgImage As Image = Image.FromHBitmap(phImage)

I've just tried as suggested but still no luck. The wrapper for the
FreeImage library I am using strictly uses Int32 rather than Intptr anyway,
I have tried using pointers but this hasn't effected it, I'm still getting 1
black pixel for any image.

This is what my function looks like at the moment,

-------------------------------------

Private Function getFreeImage(ByVal iFileName As String) As Image
Try

'Create a Free Image wrapper object and then load the image,
recieving an IntPtr

Dim pFIWImage As New freeImage_Wrapper()
Dim pIntFIHandle As IntPtr =
pFIWImage.FreeImage_Load(freeImage_Wrapper.FreeImage_GetFileType(iFileName,
0), iFileName, 0)
Dim pBmpBitmap As Bitmap = New
Bitmap(Convert.ToInt32(pFIWImage.FreeImage_GetWidth(pIntFIHandle)),
Convert.ToInt32(pFIWImage.FreeImage_GetHeight(pIntFIHandle)))

'Create a new comatible DC using the Framework, rather than Windows
API's

Dim pGraGraphics As Graphics = Graphics.FromImage(pBmpBitmap)
Dim pIPrHDC As IntPtr = pGraGraphics.GetHdc

'Get the parts of the image needed to create a DDB as IntPtr's

Dim pBIHInfoHeader As IntPtr =
pFIWImage.FreeImage_GetInfoHeader(pIntFIHandle)
Dim pIPrBits As IntPtr = pFIWImage.FreeImage_GetBits(pIntFIHandle)
Dim pBIoInfo As IntPtr = pFIWImage.FreeImage_GetInfo(pIntFIHandle)

'Create a DDB

Dim pIntHBitmap As IntPtr = CreateDIBitmap(pIPrHDC.ToInt32,
pBIHInfoHeader, CBM_INIT, pIPrBits, pBIoInfo, DIB_RGB_COLORS)

'Convert into a .NET image

Dim pImgImage As Image = Image.FromHbitmap(pIntHBitmap)

'Release the DC and unload the image

Call pGraGraphics.ReleaseHdc(pIPrHDC)
Call pFIWImage.FreeImage_Unload(pIntFIHandle)

'Return the .NET image

Return (pImgImage)
Catch ex As Exception
MessageBox.Show(ex.ToString)
Return (Nothing)
End Try
End Function

-------------------------------------

I'm slightly confused as to how you can actually change the signature of an
API call? I notice on MSDN with reference to CreateDIBitmap that it uses
pointers int the call, hence I am using IntPtr's in the declaration, for
example

Private Declare Function CreateDIBitmap Lib "gdi32.dll" (ByVal hdc As Int32,
ByRef lpInfoHeader As IntPtr, ByVal dwUsage As Int32, ByRef lpInitBits As
IntPtr, ByRef lpInitInfo As IntPtr, ByVal wUsage As Int32) As IntPtr

On MSDN it says that the return value is a handle to the HBitmap if
successful, I am getting a returned value every time without fail, but it is
allways the same value, if I use Err.LastDLLError I get code 8, not that I
know what that means exactly.

I haven't actually found any examples anywhere of CreateDIBitmap being used
in VB.NET. If this cannot be achieved in VB.NET I do not mind using C#,
after all it is only a tiny plugin that I am creating which wraps the
FreeImage library. Thanks for your help Tom, I shall keep trying different
deformations of data types.

Nick.

--
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
"No matter. Whatever the outcome, you are changed."

Fergus - September 5th 2003
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
 
N

Nak

Hi again,

I have just made a discovery, I get the same 1 black pixel if I pass
zero pointers to the CreateDIBitmap function, so surely it must be the way
the data is being passed. I can't see that what I am doing is that wrong,
surely?

-------------------

FIBITMAP *dib = FreeImage_Load(FIF_PNG, "test.png", PNG_DEFAULT);
HBITMAP bitmap = CreateDIBitmap(hDC, FreeImage_GetInfoHeader(dib),
CBM_INIT, FreeImage_GetBits(dib), FreeImage_GetInfo(dib), DIB_RGB_COLORS);

-------------------

Referring to the above, FIBITMAP is of Int32 type, simply aliased.
According to the C# wrapper FreeImage_GetInfoHeader returns the correct data
type for the API, so does FreeImage_GetInfo. FreeImageGetBits on the other
hand returns an Int32, which I *presume* is a pointer to an array, which
surely I could get to by using new IntPtr(address) ?

More deformations needed I think!

Nick.

--
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
"No matter. Whatever the outcome, you are changed."

Fergus - September 5th 2003
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
 
T

Tom Spink

strictly uses Int32

I don't understand, what do you mean, strictly? If the C++ function is
FIBITMAP*, then it's a pointer...

--
HTH,
-- Tom Spink, Über Geek

Please respond to the newsgroup,
so all can benefit

" System.Reflection Master "

==== Converting to 2002 ====
Remove inline declarations
 
N

Nak

Hi Tom,
I don't understand, what do you mean, strictly? If the C++ function is
FIBITMAP*, then it's a pointer...

What I am saying is that the API's signature should be written correctly,
the FreeImage library returns complete classes containing the Bitmap Header
data, and not pointers too, if I go changing the signature so it returns a
pointer it isn't going to change the underlying code!!

What I need to be able to do is get the required information from the
FreeImage API's and pass a pointer to the relevant data to the API, which I
presumed was ByRef but I am not so sure if it is treated the same in C++.

I know full well that if the API description contains a * that it is a
pointer, but in VB.NET you can't just make pointers to objects, or can you?
ByRef isn't technically the same, or is it?

I have made a C# version of exactly the same thing and it still doesn't
work, it seems to me that CreateDIBitmap might not be compatible with .NET,
I haven't found one example of this FreeImage library being used in .NET nor
CreateDIBitmap. Maybe C++ .NET, that should have no problems surely?

Fun fun fun

Nick.

--
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
"No matter. Whatever the outcome, you are changed."

Fergus - September 5th 2003
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
 
N

Nak

All working!!!

I stuck with the C# version and kept trying many different combinations, I
eventually didn't pass anything by reference and the only pointer that was
passed was for the bitmap bits.

Talk about look of shock on my face when the thing actually worked! I
thought I was flogging a dead badger with a pastrami!!

Nick.

--
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
"No matter. Whatever the outcome, you are changed."

Fergus - September 5th 2003
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
 
N

Nak

Weyhey now working in VB.NET!

Loads of types now!

Nick.

--
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
"No matter. Whatever the outcome, you are changed."

Fergus - September 5th 2003
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
 
Joined
Sep 16, 2005
Messages
1
Reaction score
0
Post some code please

Hi.

I'm in the similar situation like you.

Can you please post some C# code as an example of converting FreeImage bitmap to C# bitmap

PLEASE :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top