C# - 捕获鼠标光标图像
背景
- 我正在编写一个屏幕捕获应用程序
- 我的代码基于此项目: http://www.codeproject.com/KB/cs/DesktopCaptureWithMouse.aspx?display=Print
- 请注意,代码也捕获了鼠标光标(这对我来说是理想的)
我的问题
- 当鼠标时代码工作正常光标是普通指针或手形图标 - 鼠标在屏幕截图上正确呈现
- 但是,当鼠标光标更改为插入点(“工字形”光标)时 - 例如在记事本中键入 - 然后代码不会工作 - 结果是我得到了光标的微弱图像 - 就像它的一个非常半透明(灰色)版本,而不是空白和光标。 白人会期望。
我的问题
- 当图像是这些“工字梁”类型图像之一时,如何捕获鼠标光标图像
- 注意:如果您单击原始文章,有人会提供建议 - 它不起作用
来源
这是来自原始文章文章。
static Bitmap CaptureCursor(ref int x, ref int y)
{
Bitmap bmp;
IntPtr hicon;
Win32Stuff.CURSORINFO ci = new Win32Stuff.CURSORINFO();
Win32Stuff.ICONINFO icInfo;
ci.cbSize = Marshal.SizeOf(ci);
if (Win32Stuff.GetCursorInfo(out ci))
{
if (ci.flags == Win32Stuff.CURSOR_SHOWING)
{
hicon = Win32Stuff.CopyIcon(ci.hCursor);
if (Win32Stuff.GetIconInfo(hicon, out icInfo))
{
x = ci.ptScreenPos.x - ((int)icInfo.xHotspot);
y = ci.ptScreenPos.y - ((int)icInfo.yHotspot);
Icon ic = Icon.FromHandle(hicon);
bmp = ic.ToBitmap();
return bmp;
}
}
}
return null;
}
BACKGROUND
- I am writing a screen capture application
- My code is based derived from this project: http://www.codeproject.com/KB/cs/DesktopCaptureWithMouse.aspx?display=Print
- Note that the code captures the the mouse cursor also (which is desirable for me)
MY PROBLEM
- Code works fine when the mouse cursor is the normal pointer or hand icon - the mouse is rendered correctly on the screenshot
- However, when the mouse cursor is changed to the insertion point (the "I-beam" cursor) - for example typing in NOTEPAD - then code doesn't work - the result is that I get a faint image of the cursor - like a very translucent (gray) version of it instead of the blank & white one would expect.
MY QUESTION
- How can I capture the mouse cursor image when the image is one of these "I-beam"-type images
- NOTE: If you click on the original article someone offers a suggestion - it doesn't work
SOURCE
This is from the original article.
static Bitmap CaptureCursor(ref int x, ref int y)
{
Bitmap bmp;
IntPtr hicon;
Win32Stuff.CURSORINFO ci = new Win32Stuff.CURSORINFO();
Win32Stuff.ICONINFO icInfo;
ci.cbSize = Marshal.SizeOf(ci);
if (Win32Stuff.GetCursorInfo(out ci))
{
if (ci.flags == Win32Stuff.CURSOR_SHOWING)
{
hicon = Win32Stuff.CopyIcon(ci.hCursor);
if (Win32Stuff.GetIconInfo(hicon, out icInfo))
{
x = ci.ptScreenPos.x - ((int)icInfo.xHotspot);
y = ci.ptScreenPos.y - ((int)icInfo.yHotspot);
Icon ic = Icon.FromHandle(hicon);
bmp = ic.ToBitmap();
return bmp;
}
}
}
return null;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
虽然我无法准确解释为什么会发生这种情况,但我想我可以展示如何解决它。
ICONINFO 结构包含两个成员 hbmMask 和 hbmColor,它们分别包含光标的掩码和颜色位图(请参阅 MSDN 页面以获取 ICONINFO 获取官方文档)。
当您为默认光标调用 GetIconInfo() 时,ICONINFO 结构包含有效的掩码和颜色位图,如下所示(注意:已添加红色边框以清楚地显示图像边界):
默认光标掩码位图< /strong>
默认光标颜色位图
当 Windows 绘制默认光标时,首先对遮罩位图进行 AND 光栅运算,然后颜色位图应用 XOR 光栅操作。 这会产生不透明的光标和透明的背景。
但是,当您为 I-Beam 光标调用 GetIconInfo() 时,ICONINFO 结构仅包含有效的掩码位图,而没有颜色位图,如下所示(注意:再次添加红色边框以清楚地显示图像边界):
I-Beam 光标遮罩位图
根据 ICONINFO 文档,I-Beam 光标是单色光标。 掩码位图的上半部分是 AND 掩码,掩码位图的下半部分是 XOR 位图。 当 Windows 绘制 I-Beam 光标时,首先使用 AND 光栅操作在桌面上绘制该位图的上半部分。 然后通过 XOR 光栅操作将位图的下半部分绘制在顶部。 在屏幕上,光标将与其后面的内容相反地显示。
评论之一您链接的原始文章提到了这一点。 在桌面上,由于光栅操作应用于桌面内容,因此光标将显示正确。 但是,当图像没有背景绘制时(如您发布的代码中所示),Windows 执行的光栅操作会导致图像褪色。
也就是说,这个更新的 CaptureCursor() 方法将处理彩色和单色光标,当光标为单色时提供纯黑色光标图像。
代码中存在一些问题,这些问题可能是问题,也可能不是问题。
While I can't explain exactly why this happens, I think I can show how to get around it.
The ICONINFO struct contains two members, hbmMask and hbmColor, that contain the mask and color bitmaps, respectively, for the cursor (see the MSDN page for ICONINFO for the official documentation).
When you call GetIconInfo() for the default cursor, the ICONINFO struct contains both valid mask and color bitmaps, as shown below (Note: the red border has been added to clearly show the image boundaries):
Default Cursor Mask Bitmap
Default Cursor Color Bitmap
When Windows draws the default cursor, the mask bitmap is first applied with an AND raster operation, then the color bitmap is applied with an XOR raster operation. This results in an opaque cursor and a transparent background.
When you call GetIconInfo() for the I-Beam cursor, though, the ICONINFO struct only contains a valid mask bitmap, and no color bitmap, as shown below (Note: again, the red border has been added to clearly show the image boundaries):
I-Beam Cursor Mask Bitmap
According to the ICONINFO documentation, the I-Beam cursor is then a monochrome cursor. The top half of the mask bitmap is the AND mask, and the bottom half of the mask bitmap is the XOR bitmap. When Windows draws the I-Beam cursor, the top half of this bitmap is first drawn over the desktop with an AND raster operation. The bottom half of the bitmap is then drawn over top with an XOR raster operation. Onscreen, The cursor will appear as the inverse of the content behind it.
One of the comments for the original article that you linked mentions this. On the desktop, since the raster operations are applied over the desktop content, the cursor will appear correct. However, when the image is drawn over no background, as in your posted code, the raster operations that Windows performs result in a faded image.
That being said, this updated CaptureCursor() method will handle both color and monochrome cursors, supplying a plain black cursor image when the cursor is monochrome.
There are some issues with the code that may or may not be a problem.
这是 Dimitar 响应的修改版本(使用 DrawIconEx),它在多个屏幕上对我有用:
Here's a modified version of Dimitar's response (using DrawIconEx) that worked for me on multiple screens:
根据其他答案,我制作了一个没有所有 Windows API 内容(对于单色部分)的版本,因为该解决方案不适用于所有单色光标。 我通过组合两个蒙版部分从蒙版创建光标。
我的解决方案:
Based on the other answers I made a version without all the Windows API stuff (for the monochrome part) because the solutions did not work for all monochrome cursors. I create the cursor from the mask by combining the two mask parts.
My solution:
这是修补版本,包含此页面上出现的错误的所有修复:
此版本适用于:
请参阅此处的工作: https://github.com /NickeManarin/ScreenToGif/blob/master/ScreenToGif/Util/Native.cs#L991
This is the patched version with all fixes for the bugs presented on this page:
This version works with:
See working, here: https://github.com/NickeManarin/ScreenToGif/blob/master/ScreenToGif/Util/Native.cs#L991
您对半透明“灰色”版本工字梁光标的描述让我想知道您是否遇到了图像缩放或光标定位错误的问题。
在该网站上发帖的一个人提供了一个(损坏的)链接,指向一份具有特殊行为的报告,我已追踪到该报告:http://www.efg2.com/Lab/Graphics/CursorOverlay.htm
该页面上的示例不是用 C# 编写的,但 codeproject 解决方案的作者可能已经做了一些事情类似,我知道我自己在很多情况下使用图形对象时都搞砸了缩放:
Your description of a translucent 'gray' version of the I-beam cursor makes me wonder if you're encountering an issue with image scaling or mispositioning of the cursor.
One of the people posting on that site provided a (broken) link to a report with peculiar behavior that I've tracked down to: http://www.efg2.com/Lab/Graphics/CursorOverlay.htm
The examples on that page are not in C# but the author of the codeproject solution may have been doing something similar and I know I've screwed up my scaling when using the graphics object on plenty of occassions myself: