从Silverlight / PInvoke中的剪贴板获取图像

时间:2012-05-08 21:14:14

标签: c# silverlight winapi pinvoke gdi+

所以......标题为。

虽然我能够找到解决方案here

但是解决方案是首先将图像写入临时文件并将其读入流中。

所以我一直在尝试修改解决方案,以下是我一直在尝试的案例 6小时 ......:

案例1)

直接从流中读取,使用:

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

转向:

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

我试图将IntPtr.Zero传递给stream参数,但IntPtr的输出结果仍为零...失败...

案例2)

让我们试试......像上面说的那样获取像素数据。

我知道我可以通过调用GetClipboardData来获取HBITMAP:

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

让我们尝试使用GetBitMapBits,假设我知道图像的大小:

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

现在至少我可以看到数据被复制,但GetBitMapBits用于16位窗口......失败

案例3)

好的,所以我应该使用GetDIBits来获取像素数据......

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

但现在问题是......我可以在哪里获得剪贴板的设备上下文......

更重要的是,我怎么知道剪贴板图像的宽度和高度......

在WPF / WinForm中,我们可以使用FromHBitmap方法轻松完成。除了写入文件并阅读之外,我想不出任何其他方式。或者写一个COM来解决这个问题......

任何人都有解决方案吗?

1 个答案:

答案 0 :(得分:0)

经过几个小时的谷歌,msdn和实验......

我发现我实际上可以使用IntPtr.Zero从hBitmap获取BitmapInfo ..

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

这将给我一个BitmapInfo,其中包含图像的宽度,高度。

然后现在我可以使用Width和Height来计算我需要的字节数组的大小,所以现在我可以使用:

//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);

有我的binaryData,我终于可以将它们映射到我的WriteableBitmap,高度,宽度,字节[]:)