原文: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环境)

本文使用的图片素材:


本文主题:

从窗体的图片中截取需要的部分,本例是验证码区域。


正文:

先贴出主要代码

  1. /// <summary>
  2. /// 指定窗口区域截图
  3. /// </summary>
  4. /// <param name="handle">窗口句柄. (在windows应用程序中, 从Handle属性获得)</param>
  5. /// <param name="rect">窗口中的一个区域</param>
  6. /// <returns></returns>
  7. public Bitmap CaptureWindow(IntPtr hWnd,RECT rect)
  8. {
  9. // 获取设备上下文环境句柄
  10. IntPtr hscrdc = GetWindowDC(hWnd);
  11.  
  12. // 创建一个与指定设备兼容的内存设备上下文环境(DC)
  13. IntPtr hmemdc = CreateCompatibleDC(hscrdc);
  14. IntPtr myMemdc = CreateCompatibleDC(hscrdc);
  15.  
  16. // 返回指定窗体的矩形尺寸
  17. RECT rect1;
  18. GetWindowRect(hWnd, out rect1);
  19.  
  20. // 返回指定设备环境句柄对应的位图区域句柄
  21. IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, rect1.Right - rect1.Left, rect1.Bottom - rect1.Top);
  22. IntPtr myBitmap = CreateCompatibleBitmap(hscrdc, rect.Right - rect.Left, rect.Bottom - rect.Top);
  23.  
  24. //把位图选进内存DC
  25. // IntPtr OldBitmap = (IntPtr)SelectObject(hmemdc, hbitmap);
  26. SelectObject(hmemdc, hbitmap);
  27. SelectObject(myMemdc, myBitmap);
  28.  
  29. /////////////////////////////////////////////////////////////////////////////
  30. //
  31. // 下面开始所谓的作画过程,此过程可以用的方法很多,看你怎么调用 API 了
  32. //
  33. /////////////////////////////////////////////////////////////////////////////
  34.  
  35. // 直接打印窗体到画布
  36. PrintWindow(hWnd, hmemdc, 0);
  37.  
  38. // IntPtr hw = GetDesktopWindow();
  39. // IntPtr hmemdcClone = GetWindowDC(myBitmap);
  40.  
  41. BitBlt(myMemdc, 0, 0, rect.Right - rect.Left, rect.Bottom - rect.Top, hmemdc, rect.Left, rect.Top, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);
  42. //SelectObject(myMemdc, myBitmap);
  43.  
  44. Bitmap bmp = Bitmap.FromHbitmap(myBitmap);
  45. DeleteDC(hscrdc);
  46. DeleteDC(hmemdc);
  47. DeleteDC(myMemdc);
  48. return bmp;
  49. }

讲解吧:

原理步骤:

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. Servlet过滤器——日志记录过滤器

    1.概述 在实际的项目开发过程中,经常需要在项目运行时,记录并在控制台中输出运行时的日志信息,便于查看项目的运行状况.本实例将介绍如何应用过滤器实现日志记录.运行本实例,将在控制台中输出项目运行时的日 ...

  2. StackOverFlow的2016统计

    http://stackoverflow.com/research/developer-survey-2016

  3. uva 1374 快速幂计算

    #include <iostream> #include <cstdio> #include <cmath> #include <cstring> #i ...

  4. TsFltMgr.sys其原因是,该系统蓝屏QQ计算机管理器!

    同事一WindowsXP系统,正常执行,关闭后,第二天无法启动.详细症状为: (1)安全模式以及带网络功能的安全模式都能够进入. (2)正常模式.还没出现WindowXP滚动栏就開始重新启动: (3) ...

  5. 12306 Android客户端的libcheckcode.so解密及修复

    源:http://blog.csdn.net/justfwd/article/details/45219895  这篇文章纯粹属于安全分析研究,请勿用于非法用途.如有侵犯到厂家,请告知作者删除 123 ...

  6. OCA读书笔记(7) - 管理数据库存储结构

    7.Managing Database Storage Structures 逻辑结构 数据库的存储结构有物理结构和逻辑结构组成的 物理结构:物理上,oracle是由一些操作系统文件组成的 SQL&g ...

  7. USM锐化之openCV实现,附赠调整对比度函数

    源地址:http://www.cnblogs.com/easymind223/archive/2012/07/03/2575277.html 常用Photoshop的玩家都知道Unsharp Mask ...

  8. Java Web Services (2) - 第2章 启动日志分析

    ZHAOFLIU-Mac:dev liuzhaofu$ ./start --seed########################################################## ...

  9. Successful Lisp - Cover

    Successful Lisp - Cover Successful Lisp: How to Understand and Use Common Lisp

  10. CSS——inline-block属性

    Inline-block 是元素 display属性的一个值 .这个名字的由来是因为,可以简单的解释为inline+block :display设置这个值的元素,兼具行内元素( inline elem ...