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

本文关键字:剪贴板 获取 图像 Silverlight PInvoke | 更新日期: 2023-09-27 18:33:38

所以.....如标题所示。

虽然我能够在这里找到解决方案。

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

所以我一直在尝试修改解决方案,这是我尝试了 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 传递到流参数中,但 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来解决这个问题。

有人有解决方案吗?

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

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

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

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

这将给我一个包含图像宽度、高度的位图信息。

然后现在我可以使用

宽度和高度来计算我需要的字节数组的大小,所以现在我可以使用:

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

有了我的二进制数据,我终于可以将它们映射到我的可写位图,包括高度、宽度、字节[] :)