我正在尝试截取应用程序的屏幕截图,我想让不属于应用程序区域的矩形部分透明。因此,例如在标准 Windows 应用程序上,我想让圆角透明。
我编写了一个快速的测试应用程序,它可以在 XP(或关闭 aero 的 vista/windows 7)上运行:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
// Just find a window to test with
IntPtr hwnd = FindWindowByCaption(IntPtr.Zero, "Calculator");
WINDOWINFO info = new WINDOWINFO();
info.cbSize = (uint)Marshal.SizeOf(info);
GetWindowInfo(hwnd, ref info);
Rectangle r = Rectangle.FromLTRB(info.rcWindow.Left, info.rcWindow.Top, info.rcWindow.Right, info.rcWindow.Bottom);
IntPtr hrgn = CreateRectRgn(info.rcWindow.Left, info.rcWindow.Top, info.rcWindow.Right, info.rcWindow.Bottom);
GetWindowRgn(hwnd, hrgn);
// fill a rectangle which would be where I would probably
// write some mask color
g.FillRectangle(Brushes.Red, r);
// fill the region over the top, all I am trying to do here
// is show the contrast between the applications region and
// the rectangle that the region would be placed in
Region region = Region.FromHrgn(hrgn);
region.Translate(info.rcWindow.Left, info.rcWindow.Top);
g.FillRegion(Brushes.Blue, region);
}
当我在 XP(或关闭 Aero 的 Vista/Windows 7)上运行这个测试应用程序时,我得到了这样的东西,这很棒,因为我可以从中得到一个异或掩码,以后可以与 BitBlt 一起使用。
删除了无效的 Imageshack 链接 - 屏幕截图
这就是问题所在,在启用了 Aero 的 Vista 或 Windows 7 上,窗口上不一定有区域,事实上在大多数情况下是没有的。谁能帮我想办法在这些平台上构建这样的面具?
以下是我已经尝试过的一些方法...
<强>1。使用 PrintWindow功能: 这不起作用,因为它会返回 Aero 关闭时窗口的屏幕截图,并且此窗口的形状与 Aero 打开时返回的窗口形状不同
2 使用 Desktop Window Manager API获取全尺寸缩略图: 这不起作用,因为它直接绘制到屏幕上,据我所知,您无法直接从此 api 获取屏幕截图。是的,我可以打开一个粉红色背景的窗口,显示缩略图,截取屏幕截图,然后隐藏这个临时窗口,但那是一种糟糕的用户体验,是一种彻底的黑客攻击,我宁愿不让自己的名字出现在上面。
<强>3。使用Graphics.CopyFromScreen或此的其他一些 pinvoke 变体: 这不起作用,因为我不能假设我需要信息的窗口位于屏幕上 z 顺序的顶部。
目前,我能想到的最佳解决方案是针对 Windows 7 和 Vista 上的特殊情况 Aero,通过对我绘制的一些图形路径进行硬编码来手动删除边角,但该解决方案会很糟糕,因为任何执行自定义蒙皮的应用程序会打破这个。
你能想到另一个或更好的解决方案吗?
如果您在这里,感谢您花时间阅读这篇文章,非常感谢您提供的任何帮助或指导!
强>强>最佳答案
如果您要查找已完成的应用程序,可以找到 7capture ,它还捕获半透明效果,因此可以将图像保存为 PNG 格式以供以后合成。
编辑:
最初的问题和评论表明您希望在 Windows Vista/7 上生成一个区域,然后您可以使用该区域来屏蔽捕获的图像的部分,就像在 Windows XP 和非 Aero UI 中所做的那样。使用区域不会给您想要的结果,因为窗口轮廓不是作为区域计算的,而是作为具有可变透明度的图像 - RGBA 计算的。该图像中的 Alpha channel 是您的蒙版,但它不是像区域那样的开关蒙版,而是渐变蒙版,其值范围从像素被完全包含到被完全屏蔽掉。
虽然它使用未记录的 API,但 http://spazzarama.wordpress.com/2009/02/12/screen-capture-with-vista-dwm/ 处的代码将捕获到 RGBA 缓冲区,然后您可以使用它来渲染或保存具有完整阴影和其他半透明效果的图像。
在DwmCapture.cs中修改
BackBufferFormat = Format.X8R8G8B8
到
BackBufferFormat = Format.A8R8G8B8
(X8->A8)
然后您应该能够从捕获的缓冲区访问通常的 RGB 数据和透明度。然后可以将其保存为 PNG 或其他带有 alpha channel 的格式以进行合成。
关于c# - 在 Windows Vista、Windows 7 中截屏,应用区域外有透明区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2986508/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
是否可以在应用程序中包含的gem代码中知道应用程序的Rails文件系统根目录?这是gem来源的示例:moduleMyGemdefself.included(base)putsRails.root#returnnilendendActionController::Base.send:include,MyGem谢谢,抱歉我的英语不好 最佳答案 我发现解决类似问题的解决方案是使用railtie初始化程序包含我的模块。所以,在你的/lib/mygem/railtie.rbmoduleMyGemclassRailtie使用此代码,您的模块将在