?
Solved

Marshal / un Marshal Bitmaps

Posted on 2006-05-19
11
Medium Priority
?
1,137 Views
Last Modified: 2011-10-03

I need to pass .NET Bitmaps into a an unmanaged library dll, and retrieve them back.

How do a marshal a .NET bitmap to the unmanaged dll?

How do I obtain a .NET bitmap back from the unmanaged dll?

0
Comment
Question by:Daeljan
  • 5
  • 3
  • 2
  • +1
11 Comments
 
LVL 28

Accepted Solution

by:
2266180 earned 800 total points
ID: 16716139
well ... best way is to convert the data to byte[] (you will probably have it in a stream, right? so just read up the byte[];) since it's binary and you also won't have any complications with the marshalling/unmarshalling.
0
 
LVL 2

Author Comment

by:Daeljan
ID: 16716158
Have you actually tried this?

Can you show me some example code marshalling an unmarshalling a bitmap this way?
A bitmap structure in .NET is more then just image data, the same goes for GDI, so I don't readily see what you mean.

Thanks
0
 
LVL 2

Author Comment

by:Daeljan
ID: 16716180
Does a native GDI bitmap have exactly the same footprint as a .NET bitmap?
I ask because I will need to unpack the bytes in the unmanaged code into a GDI bitmap.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 28

Expert Comment

by:2266180
ID: 16716258
I don't have ready made code, but it's pretty straitforward (it's the "tehnique" I used for any data exchange that needs to have a specific format):
save the bitmap intro a memorystream
read up the byte[] data
copy it to the marshal pointer

code looks something similar to this:
            byte[] src;
            Bitmap bmp;
            MemoryStream stream = new MemoryStream();
            bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
            stream.Seek(0,SeekOrigin.Begin);
            stream.Write(src,0,stream.Size);
            Marshal.Copy(src,0,ptr,src.Length);

0
 
LVL 2

Author Comment

by:Daeljan
ID: 16716638
I've done similar marshalling in the past, but the thing is, how can this bitmap be reconstructed in the unmanaged c++ code - thats the other half of the problem.

ahh, I see the wisdom now, it's the same as saving to/ loading from a ram-disk! So the prototype for the image exchange would be

in C++:

void Func(unsigned char *pBitmapArray, int * pBitmapArrayLength);

and in C#:

void Func(IntPtr pBitmapArray, IntPtr pBitmapArrayLength);

The length is a pointer too because Func() may change the image, hence the size.

ok, so you call Func() in C# passing in an image to be changed somehow, how would you unmarshall the bytes back into a memory stream? I can handle the int ok, so just assume that we already have the length.

0
 
LVL 48

Assisted Solution

by:AlexFM
AlexFM earned 400 total points
ID: 16716826
Use Bitmap.LockBits Method and pass BitmapData.Scan0 Property as pBitmapArray parameter. You can do this if BitmapData.Stride is equal to bitmap width * pixel length.
In any case, it is possible to copy bitmap pixels to Byte array and copy this array to unmanaged memory block with Marshal.Copy function.
0
 
LVL 28

Expert Comment

by:2266180
ID: 16716905
for the other half of the problem:
the bitmap is saved like into a file, but instead it's in memory. so basically what you do on the c++ side is open the bitmap from a file, but then again, you don't open it from a file, but from a memorystram. c++ should have such clasess/functions.

for the image exchange:
if the prototype is void Func(IntPtr pBitmapArray, IntPtr pBitmapArrayLength);
then my code changes to something like this:
                  byte[] dst;
                  int len = Marshal.ReadInt32(lenptr);
                  Marshal.Copy(ptr,dst,0,len);
                  MemoryStream stream = new MemoryStream();
                  stream.Write(dst,0,len);
                  stream.Seek(0,SeekOrigin.Begin);
                  Bitmap bmp = new Bitmap(stream);
0
 
LVL 2

Author Comment

by:Daeljan
ID: 16717799
Can someone please tell me if I can use a Bitmap object in unmanaged code?
The unmanaged code will link to a single threaded static library, hence I need to build it accordingly with the option:

C/C++ / Code Generation / Run Time Library / Single-threaded

I realise that this is a little off the thread but it is all part of the same problem, and before I test out the solution I need to be able to create the unmanaged dll.

I'm using VS 7.1 (2003). I created an MFC dll, but I cant seem to get access to these objects.

I'm really stuck in this one and I'm up against a deadline.

Many thanks
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 16717911
You can pass to unmanaged code plain data like int, string, array of pixels. Can you describe exactly what do you want to do in umnanaged code and why do you need to write unmanaged code?
0
 
LVL 10

Expert Comment

by:prakash_prk
ID: 16718405
Try this plz...
------------------------------------------------------------------------------

IntPtr hBitmapHandle, resultHBitMap;

// hBitmapHandle get the hbitmap from the unmanaged code
Bitmap myBitMap = Bitmap.FromHbitmap(hBitmapHandle);

resultHBitMap = myBitMap.GetHbitmap();

//pass resultHBitMap to unmanaged code
------------------------------------------------------------------------------

regards
prakash
0
 
LVL 2

Author Comment

by:Daeljan
ID: 16733612
Hi there,

I split the points on this one. My original solution was a multi-mode dll written in C++. Due to some instability in the application, I began to doubt that this dll was ok, hence the change of plan to Win32 (it was pure number crunching on bitmap pixels).

Anyhow, as it happens, another module somewhere in the app was violating memory and there was nothing wrong with the multi-mode dll, so I havent needed to try any of your solutions out. However, as they were informative enough, I have split the points.

Thanks.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
Whether it be Exchange Server Crash Issues, Dirty Shutdown Errors or Failed to mount error, Stellar Phoenix Mailbox Exchange Recovery has always got your back. With the help of its easy to understand user interface and 3 simple steps recovery proced…
Suggested Courses

621 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question