简体   繁体   中英

Get image from Clipboard in Silverlight/PInvoke

So..... as titled.

Althought I was able to find a solution here .

But the solution is first writting the image into a temporary file and read it into stream.

So I have been trying to modify the solution, here is the cases I have been trying for 6 hours ...:

Case 1)

Read directly from stream instead using:

internal static extern int GdipSaveImageToStream(GpImage *image, IStream* stream, GDIPCONST CLSID* clsidEncoder, GDIPCONST EncoderParameters* encoderParams);

Which turns to:

[DllImport("gdiplus.dll", ExactSpelling=true, CharSet=CharSet.Unicode)]
internal static extern int GdipSaveImageToStream(IntPtr image, IntPtr stream, [In] ref Guid Encoder, IntPtr encoderParams);

I tried to pass in IntPtr.Zero into stream parameter, but the out result to the IntPtr is still zero... Fail...

Case 2)

Let's try... get the pixel data like one of the post said.

I know I can get HBITMAP by calling GetClipboardData:

[DllImport("user32.dll")]
static extern IntPtr GetClipboardData(uint uFormat);

So let's try using GetBitMapBits, assuming I know the size of the image:

[DllImport("gdi32.dll")]
static extern int GetBitmapBits(IntPtr hbmp, int cbBuffer, [Out] byte[] lpvBits);

Now at least I can see data being copy, but GetBitMapBits is for 16-bit windows... Fail

Case 3)

Ok, so I should use GetDIBits to get the pixel data...

[DllImport("gdi32.dll")]
public static extern int GetDIBits(IntPtr hdc, IntPtr hbmp, uint uStartScan,
                                   uint cScanLines, [Out] byte[] lpvBits, ref BitmapInfo lpbmi, uint uUsage);

But now the problem is.... where I can get the device context for clipboard......

And more over, how do I even know about the Width and Height of the Clipboard Image.....

In WPF/WinForm we would have FromHBitmap method to do it easily. I can't think of any other way other than writting into file and read it. Or write a COM to solve this problem....

Anyone have a solution?

After hours of google, msdn and experiments...

I found out that I can actually get the BitmapInfo from hBitmap by using IntPtr.Zero..

hDC = User32.GetDC(IntPtr.Zero);
Gdi32.GetDIBits(hDC, hBitmap, 0, 1, null, ref bi, DIB_RGB_COLORS);

which will give me a BitmapInfo that contains Width, Height of the image.

Then now I could use the Width and Height to caculate the size of byte array that I will need, so now I can use:

//Similiarly, hMemDC is also a device context that created using IntPtr.Zero.
Gdi32.GetDIBits(hMemDC, hBitmap, 0, (uint)pixelHeight, binaryData, ref bi, DIB_RGB_COLORS);

There goes my binaryData, I can finally maps them to my WriteableBitmap with Height, Width, Byte[] :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM