C#区域截图——调用API截图
前言:截图对于一个C++开发者来说无非是小菜一碟,也有朋友使用C#的 Graphics.CopyFromScreen 方法屏幕操作,作为一名整天想着用 C++ 开发游戏的初级 C#.NET 的程序员的我,只是自己研究区域截图,失败 n 多次,最后在半梦半醒中弄出来的简单的Demo,简单的分享一下而已。如此的班门弄斧,着实不堪,另外我的 C++ 水平也是处于入门水准,如果该博客有什么问题,请各位朋友留言指正,谢谢关照!
附件及其他:
C#的 Graphics.CopyFromScreen 方法 https://msdn.microsoft.com/zh-cn/library/fw1kt6f9.aspx
附件:http://files.cnblogs.com/files/herbertchina/GetFormDemo.zip
本文Demo:(VS2010环境)
本文使用的图片素材:

本文主题:
从窗体的图片中截取需要的部分,本例是验证码区域。
正文:
先贴出主要代码
/// <summary>
/// 指定窗口区域截图
/// </summary>
/// <param name="handle">窗口句柄. (在windows应用程序中, 从Handle属性获得)</param>
/// <param name="rect">窗口中的一个区域</param>
/// <returns></returns>
public Bitmap CaptureWindow(IntPtr hWnd,RECT rect)
{
// 获取设备上下文环境句柄
IntPtr hscrdc = GetWindowDC(hWnd); // 创建一个与指定设备兼容的内存设备上下文环境(DC)
IntPtr hmemdc = CreateCompatibleDC(hscrdc);
IntPtr myMemdc = CreateCompatibleDC(hscrdc); // 返回指定窗体的矩形尺寸
RECT rect1;
GetWindowRect(hWnd, out rect1); // 返回指定设备环境句柄对应的位图区域句柄
IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, rect1.Right - rect1.Left, rect1.Bottom - rect1.Top);
IntPtr myBitmap = CreateCompatibleBitmap(hscrdc, rect.Right - rect.Left, rect.Bottom - rect.Top); //把位图选进内存DC
// IntPtr OldBitmap = (IntPtr)SelectObject(hmemdc, hbitmap);
SelectObject(hmemdc, hbitmap);
SelectObject(myMemdc, myBitmap); /////////////////////////////////////////////////////////////////////////////
//
// 下面开始所谓的作画过程,此过程可以用的方法很多,看你怎么调用 API 了
//
///////////////////////////////////////////////////////////////////////////// // 直接打印窗体到画布
PrintWindow(hWnd, hmemdc, 0); // IntPtr hw = GetDesktopWindow();
// IntPtr hmemdcClone = GetWindowDC(myBitmap); BitBlt(myMemdc, 0, 0, rect.Right - rect.Left, rect.Bottom - rect.Top, hmemdc, rect.Left, rect.Top, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);
//SelectObject(myMemdc, myBitmap); Bitmap bmp = Bitmap.FromHbitmap(myBitmap);
DeleteDC(hscrdc);
DeleteDC(hmemdc);
DeleteDC(myMemdc);
return bmp;
}
讲解吧:
原理步骤:
1、通过窗体 handle 创建设备上下文环境
2、根据上下文环境句柄建立对应的与设备兼容的内存设备上下文环境(理解成一块画板,内存上的)
3、通过窗体句柄得到长宽,通过CreateCompatibleBitmap得到窗体对应的设备环境句柄对应的位图区域(理解成自然界的一个美丽的景色)
4、通过 SelectObject 指向性,把 3 中的位图区域句柄对应到 2 中的内存设备上下文中(理解成,我需要画这大自然的美丽景色,我需要有相应的画布,这里就是在画板上固定画布)
5、绘图,包括各种 API 绘图或获取图形
6、此处很重要,因为我们不是要过去框架的整体图形,我们要的是局部的,于是,我们可以通过 1 、2 、3 、4 的步骤,再建设一块画布(第三步有一点区别,就是长宽)
7、通过 BitBlt 方法把之前画好的画的一个区域复制到我们新建的画板上, BitBlt 的功能是“对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境”
8、然后就简单了,Bitmap bmp = Bitmap.FromHbitmap(myBitmap);把我们复制出来的第二块画板上的画生成位图图像
9、再进行什么操作就随你了
10、最后,最后,最最重要的是……不要忘了使用 DeleteDC 函数清除第 1 、 2 中建的上下文环境,因为这是 API,没有Java的自动清理机制
再者:
再者,哥们我是初学者,文章仅供参考,有什么问题可以百度、google,然后就是,我上面说的一定有问题,请看明白的朋友指正留言,帮助下小友学习一二!谢谢!
C#区域截图——调用API截图的更多相关文章
- [转]c#调用API截图
转自http://blog.csdn.net/hailiannanhai/article/details/6281471 要想完成这个功能,首先要了解一下在C#中如何调用API(应用程序接口)函数.虽 ...
- 调用API函数,在窗口非客户区绘图(通过GetWindowDC获得整个窗口的DC,就可以随意作画了)
http://hi.baidu.com/3582077/item/77d3c1ff60f9fa5ec9f33754 调用API函数,在窗口非客户区绘图 GDI+的Graphics类里有个FromHdc ...
- WPF 调用API修改窗体风格实现真正的无边框窗体
原文:WPF 调用API修改窗体风格实现真正的无边框窗体 WPF中设置无边框窗体似乎是要将WindowStyle设置为None,AllowTransparency=true,这样才能达到WinForm ...
- C#中调用API
介绍 API( Application Programming Interface ),我想大家不会陌生,它是我们Windows编程的常客,虽然基于.Net平台的C#有了强大的类库,但是,我们还是不能 ...
- 一个 C# 获取高精度时间类(调用API QueryP*)
如果你觉得用 DotNet 自带的 DateTime 获取的时间精度不够,解决的方法是通过调用 QueryPerformanceFrequency 和 QueryPerformanceCounter这 ...
- ABP手机端调用API时的CORS
这个问题其实很早就考虑了,当时因为也没有特别着急去解决这个问题,就一直拖着.... 好吧,拖延症是不好的,所有不懒得做的,终将会逼着你去再很短的时间内去解决问题...实现项目 改写一个已有的webfo ...
- C#调用API函数EnumWindows枚举窗口的方法
原文 http://blog.csdn.net/dengta_snowwhite/article/details/6067928 与C++不同,C#调用API函数需要引入.dll文件,步骤如下: 1. ...
- 在C#中调用API获取网络信息和流量
原文 在C#中调用API获取网络信息和流量 最近一项目中要求显示网络流量,而且必须使用C#. 事实上,调用 IpHlpApi.dll 的 GetIfTable API 可以轻易获得网络信息和网络流量. ...
- HttpClient调用api
/// <summary> /// 模拟调用API /// </summary> /// <param requestUrl="">请求地址&l ...
随机推荐
- JQuery+AJAX实现搜索文本框的输入提示功能
平时使用谷歌搜索的时候发现只要在文本框里输入部分单词或字母,下面马上会弹出一个相关信息的内容框可供选择.感觉这个功能有较好的用户体验,所以也想在自己的网站上加上这种输入提示框. 实现的原理其实很简单, ...
- sql server 2005 外围应用配置器
想要实现sql server 2005 远程连接数据库,我们必需要用到sql05上自带的外围配置器,以下是对它的一些配置上的介绍: 首先我们要打开sql05外围配置器,例如以下图: 打开后,我们如今就 ...
- hdu 4455 Substrings (DP 预处理思路)
Substrings Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- Swift - 本地数据的保存与加载(使用NSCoder将对象保存到.plist文件)
下面通过一个例子将联系人数据保存到沙盒的“documents”目录中.(联系人是一个数组集合,内部为自定义对象). 功能如下: 1,点击“保存”将联系人存入userList.plist文件中 2,点击 ...
- linux公社的大了免费在线android资料
2011年linux数据库的android在线分享 linux公社:开源公社 本文撰写:杨凯专属频道 2011年9月12日 21:39 <目录> Android 3 ...
- Eclipse在点击运行后不能自动保存的解决
今天在eclipse上写程序调试时,发现当我点击运行按键之后,并不能在运行前帮我自动保存,也就是说每次修改代码之后, 运行的还是前一次运行之前的代码,并不是修改之后的代码,因此通过在网上搜索解决方案之 ...
- Git 图解剖析(转)
git中文件内容并没有真正存储在索引(.git/index)或者提交对象中,而是以blob的形式分别存储在数据库中(.git/objects),并用SHA-1值来校验. 索引文件用识别码列出相关的bl ...
- 一句话解释JVM中空间分配担保的问题
先解释YGC: 当对象生成在EDEN区失败时,出发一次YGC,先扫描EDEN区中的存活对象,进入S0区,S0放不下的进入OLD区,再扫描S1区,若存活次数超过阀值则进入OLD区,其它进入S0区,然后S ...
- Test oracle db iops
Today, i need to test one database's iops and do something for oracle db's io test. How to test the ...
- VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池
VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池 在上一节我们创建了完整克隆的自动专有桌面池,在创建过程比较缓慢,这次我们将学习创建Vi ...