原文: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截图的更多相关文章

  1. [转]c#调用API截图

    转自http://blog.csdn.net/hailiannanhai/article/details/6281471 要想完成这个功能,首先要了解一下在C#中如何调用API(应用程序接口)函数.虽 ...

  2. 调用API函数,在窗口非客户区绘图(通过GetWindowDC获得整个窗口的DC,就可以随意作画了)

    http://hi.baidu.com/3582077/item/77d3c1ff60f9fa5ec9f33754 调用API函数,在窗口非客户区绘图 GDI+的Graphics类里有个FromHdc ...

  3. WPF 调用API修改窗体风格实现真正的无边框窗体

    原文:WPF 调用API修改窗体风格实现真正的无边框窗体 WPF中设置无边框窗体似乎是要将WindowStyle设置为None,AllowTransparency=true,这样才能达到WinForm ...

  4. C#中调用API

    介绍 API( Application Programming Interface ),我想大家不会陌生,它是我们Windows编程的常客,虽然基于.Net平台的C#有了强大的类库,但是,我们还是不能 ...

  5. 一个 C# 获取高精度时间类(调用API QueryP*)

    如果你觉得用 DotNet 自带的 DateTime 获取的时间精度不够,解决的方法是通过调用 QueryPerformanceFrequency 和 QueryPerformanceCounter这 ...

  6. ABP手机端调用API时的CORS

    这个问题其实很早就考虑了,当时因为也没有特别着急去解决这个问题,就一直拖着.... 好吧,拖延症是不好的,所有不懒得做的,终将会逼着你去再很短的时间内去解决问题...实现项目 改写一个已有的webfo ...

  7. C#调用API函数EnumWindows枚举窗口的方法

    原文 http://blog.csdn.net/dengta_snowwhite/article/details/6067928 与C++不同,C#调用API函数需要引入.dll文件,步骤如下: 1. ...

  8. 在C#中调用API获取网络信息和流量

    原文 在C#中调用API获取网络信息和流量 最近一项目中要求显示网络流量,而且必须使用C#. 事实上,调用 IpHlpApi.dll 的 GetIfTable API 可以轻易获得网络信息和网络流量. ...

  9. HttpClient调用api

    /// <summary> /// 模拟调用API /// </summary> /// <param requestUrl="">请求地址&l ...

随机推荐

  1. 窗口绘制有关的消息整理 WM_PAINT, WM_NCPAINT, WM_ERASEBKGND

    WM_PAINTWM_PAINT是Windows窗口系统中一条重要的消息,应用程序通过处理该消息实现在窗口上的绘制工作. WM_NCPAINT当窗口客户区以外的部分(如窗口标题栏.菜单栏等)需要需要重 ...

  2. clear_logs.py修改

    #!/usr/bin/env python#encoding=utf-8"""清空最后修改时间跑今天7天以前的所有文件"""#指定监控的路径 ...

  3. Extract Datasets

    *&---------------------------------------------------------------------* *& Report ZTEST2013 ...

  4. 基于Apriori算法的Nginx+Lua+ELK异常流量拦截方案 郑昀 基于杨海波的设计文档(转)

    郑昀 基于杨海波的设计文档 创建于2015/8/13 最后更新于2015/8/25 关键词:异常流量.rate limiting.Nginx.Apriori.频繁项集.先验算法.Lua.ELK 本文档 ...

  5. 使用Delphi声明C++带函数的结构体实战 good

    在小组开发中,应用程序部分采用Delphi7,一些组件使用C++做.在今天将一个动态库的C++接口声明头文件转换为D7的Unit单元时,一切都很顺利,直到遇到下面这样一个另类的东西: typedef ...

  6. Eclipse插件引入jar包的方法(转)

    搞了两天,终于找到解决办法了.原来  Eclipse 插件项目引入外面的jar包不能用   build path---->add external jars的方法. 先说明两个概念:类加载器,O ...

  7. 14.5.2 Changing the Number or Size of InnoDB Redo Log Files 改变InnoDB Redo Log Files的数量

    14.5.2 Changing the Number or Size of InnoDB Redo Log Files 改变InnoDB Redo Log Files的数量 改变InnoDB redo ...

  8. 外语学习强烈推荐Rosetta Stone

    外语学习强烈推荐Rosetta Stone 外语学习强烈推荐Rosetta Stone

  9. Swift供选链接

    函数是运行特定任务的代码自包括块. 给定一个函数名称标识, 当运行其任务时就能够用这个标识来进行"调用". Swift的统一的功能语法足够灵活来表达不论什么东西,不管是甚至没有參数 ...

  10. 登录RMAN 报告ORA-12162:TNS:net service name is incorrectly specified错

    登录RMAN 报告ORA-12162:TNS:net service name is incorrectly specified错 [oracle@localhost admin]$ date Tue ...