转自http://blog.csdn.net/hailiannanhai/article/details/6281471

要想完成这个功能,首先要了解一下在C#中如何调用API(应用程序接口)函数。虽然在.Net框架中已经提供了许多类库,这些类库的功能也十分强大,但对于一些Windows底层编程来说,还是要通过调用这些API函数才可以实现。所有API都在"Kernel"、"User "和"GDI"三个库中得以运行:其中"Kernel",他的库名为 "KERNEL32.DLL", 他主要用于产生与操作系统之间的关联,譬如:程序加载,上下文选择,文件输入输出,内存管理等等。"User "这个类库在Win32中名叫 "USER32.DLL"。 它允许管理全部的用户接口。譬如:窗口 、菜单 、对话框 、图标等等。"GDI"(图象设备接口),它在Win32中的库名为:"GDI32.dll",它是图形输出库。使用GDI Windows"画"出窗口、菜单以及对话框等;它能创建图形输出;它也能保存图形文件。由于本文所涉及到是图象问题,所有调用的类库是"GDI32.dll"。在本文程序中我们使用的API函数是"BitBlt",这个函数对于广大程序员来说,一定不感觉到陌生,因为在图象处理方面他的用途是相对广的,在用其他程序语言编程中,时常也要和他打交道。在.Net FrameWork SDK中有一个名字空间"System.Runtime.InteropServices",此名字空间提供了一系列的类来访问COM对象,和调用本地的 API函数。下面是在C#中声明此函数:

  1. [ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
  2. private static extern bool BitBlt (
  3. IntPtr hdcDest , // 目标 DC的句柄
  4. int nXDest ,
  5. int nYDest ,
  6. int nWidth ,
  7. int nHeight ,
  8. IntPtr hdcSrc , // 源DC的句柄
  9. int nXSrc ,
  10. int nYSrc ,
  11. System.Int32 dwRop // 光栅的处理数值
  12. ) ;

通过上面这个声明,就可以在下面的代码中使用此函数了。

下面是用C#做屏幕捕获程序的具体实现步骤:

(1).首先要获得当前屏幕的graphic对象,通过以下代码可以实现:

  1. Graphics g1 = this.CreateGraphics ( ) ;

(2).创建一个Bitmap对象,并且这个Bitmap对象的大小是当前屏幕:

首先要获得当前屏幕的大小,通过名字空间"System.Windows.Forms"中的"Screen"类的GetWorkingArea()方法,可以实现。下面是得到当前屏幕的长(Height)和宽(Width):

  1. Rectangle rect = new Rectangle ( ) ;
  2. rect = Screen.GetWorkingArea ( this ) ;
  3. "屏幕宽" rect.Width ;
  4. "屏幕长" rect.Height ;

至此就可以得到我们想要的Bitmap了,通过下列语句可以实现:

  1. Image MyImage = new Bitmap ( rect.Width , rect.Height , g1 ) ;
  2. //创建以屏幕大小为标准的位图

在C#中,可以使用System.Windows.SystemParameters获取有关屏幕真实状态的基本信息。

  1. 获取屏幕像素:    

  1. SystemParameters.FullPrimaryScreenHeight
    SystemParameters.FullPrimaryScreenWidth

  2. 获取工作区(不包括任务栏)像素:

  1. SystemParameters.WorkArea.Height
  2. SystemParameters.WorkArea.Width

C# 获得屏幕大小

  1. Rectangle rect=System.Windows.Forms.SystemInformation.VirtualScreen;
  2. int width=rect.Width;
  3. int height=rect.Height;

(3).获得当前屏幕和此Bitmap对象的DC,这可以通过下列语句实现:

  1. //得到屏幕的DC
  2. IntPtr dc1 = g1.GetHdc ( ) ;
  3. //得到Bitmap的DC
  4. IntPtr dc2 = g2.GetHdc ( ) ;

(4).调用API函数,把当前屏幕拷贝到创建的Bitmap中:

  1. BitBlt ( dc2 , , , rect.Width , rect.Height , dc1 , , , ) ;

(5).释放当前屏幕和此Bitmap对象的DC,通过下面代码可以实现:

  1. //释放掉屏幕的DC
  2. g1.ReleaseHdc ( dc1 ) ;
  3. //释放掉Bitmap的DC
  4. g2.ReleaseHdc ( dc2 ) ;

(6).保存Bitmap对象,形成jpg图片:

  1. MyImage.Save ( @"c:Capture.jpg" , ImageFormat.Jpeg );

当然你也可以根据自己的需要,把屏幕以其他图片的格式来保存,如果你想把图片保存为位图文件,可以把"ImageFormat.Jpeg"改换成"ImageFormat.Bmp";想把图片保存为Gif文件,就把"ImageFormat.Jpeg"改换成"ImageFormat.Gif"。你可以保存的文件类型大概有十多种,这里就不一一介绍了,当然你也要相应改变保存文件的后缀。

用C#来捕获屏幕的源程序代码(Capture.cs):

了解上面的这些步骤的实现方法,就可以得到用C#捕获屏幕的源程序,如下:

  1. using System ;
  2. using System.Drawing ;
  3. using System.Collections ;
  4. using System.ComponentModel ;
  5. using System.Windows.Forms ;
  6. using System.Data ;
  7. using System.Drawing.Imaging ;
  8. public class Form1 : Form.
  9. {
  10. private Button button1 ;
  11. private System.ComponentModel.Container components = null ;
  12.  
  13. public Form1 ( )
  14. {
  15. //初始化窗体中的各个组件
  16. InitializeComponent ( ) ;
  17. }
  18. // 清除程序中使用过的资源
  19. protected override void Dispose ( bool disposing )
  20. {
  21. if ( disposing )
  22. {
  23. if ( components != null )
  24. {
  25. components.Dispose ( ) ;
  26. }
  27. }
  28. base.Dispose ( disposing ) ;
  29. }
  30. private void InitializeComponent ( )
  31. {
  32. button1 = new Button ( );
  33. SuspendLayout ( ) ;
  34. button1.Location = new System.Drawing.Point ( , ) ;
  35. button1.Name = "button1" ;
  36. button1.Size = new System.Drawing.Size ( , ) ;
  37. button1.TabIndex = ;
  38. button1.Text = "捕获" ;
  39. button1.Click += new System.EventHandler ( button1_Click ) ;
  40.  
  41. AutoScaleBaseSize = new System.Drawing.Size ( , ) ;
  42. ClientSize = new System.Drawing.Size ( , ) ;
  43. Controls.Add ( button1 ) ;
  44. MaximizeBox = false ;
  45. MinimizeBox = false ;
  46. Name = "Form1" ;
  47. Text = "C#捕获当前屏幕!" ;
  48. ResumeLayout ( false ) ;
  49.  
  50. }
  51. //声明一个API函数
  52. [ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
  53. private static extern bool BitBlt (
  54. IntPtr hdcDest , // 目标 DC的句柄
  55. int nXDest ,
  56. int nYDest ,
  57. int nWidth ,
  58. int nHeight ,
  59. IntPtr hdcSrc , // 源DC的句柄
  60. int nXSrc ,
  61. int nYSrc ,
  62. System.Int32 dwRop // 光栅的处理数值
  63. ) ;
  64.  
  65. static void Main ( )
  66. {
  67. Application.Run ( new Form1 ( ) ) ;
  68. }
  69. private void button1_Click ( object sender , System.EventArgs e )
  70. {
  71. //获得当前屏幕的大小
  72. Rectangle rect = new Rectangle ( ) ;
  73. rect = Screen.GetWorkingArea ( this ) ;
  74. //创建一个以当前屏幕为模板的图象
  75. Graphics g1 = this.CreateGraphics ( ) ;
  76. //创建以屏幕大小为标准的位图
  77. Image MyImage = new Bitmap ( rect.Width , rect.Height , g1 ) ;
  78. Graphics g2 = Graphics.FromImage ( MyImage ) ;
  79. //得到屏幕的DC
  80. IntPtr dc1 = g1.GetHdc ( ) ;
  81. //得到Bitmap的DC
  82. IntPtr dc2 = g2.GetHdc ( ) ;
  83. //调用此API函数,实现屏幕捕获
  84. BitBlt ( dc2 , , , rect.Width , rect.Height , dc1 , , , ) ;
  85. //释放掉屏幕的DC
  86. g1.ReleaseHdc ( dc1 ) ;
  87. //释放掉Bitmap的DC
  88. g2.ReleaseHdc ( dc2 ) ;
  89. //以JPG文件格式来保存
  90. MyImage.Save ( @"c:Capture.jpg" , ImageFormat.Jpeg );
  91. MessageBox.Show ( "当前屏幕已经保存为C盘的capture.jpg文件!" ) ;
  92. }
  93. }

[转]c#调用API截图的更多相关文章

  1. C#区域截图——调用API截图

    原文:C#区域截图——调用API截图 前言:截图对于一个C++开发者来说无非是小菜一碟,也有朋友使用C#的 Graphics.CopyFromScreen 方法屏幕操作,作为一名整天想着用 C++ 开 ...

  2. C#中调用API

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

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

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

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

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

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

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

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

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

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

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

  8. HttpClient调用api

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

  9. 32位汇编第四讲,干货分享,汇编注入的实现,以及快速定位调用API的数量(OD查看)

    32位汇编第四讲,干货分享,汇编注入的实现,以及快速定位调用API的数量(OD查看) 昨天,大家可能都看了代码了,不知道昨天有没有在汇编代码的基础上,实现注入计算器. 如果没有,今天则会讲解,不过建议 ...

随机推荐

  1. [大牛翻译系列]Hadoop(7)MapReduce:抽样(Sampling)

    4.3 抽样(Sampling) 用基于MapReduce的程序来处理TB级的数据集,要花费的时间可能是数以小时计.仅仅是优化代码是很难达到良好的效果. 在开发和调试代码的时候,没有必要处理整个数据集 ...

  2. robots.txt用法

    主要作用是告诉蜘蛛爬虫该网站下哪些内容能抓取,哪些内容不能抓取.虽然可以没有robots.txt这个文件,默认就抓取该网站的所有文件,对搜索引擎爬虫没有任何的影响,但是如果你想控制蜘蛛的检索间隔,你就 ...

  3. Array和ArrayList的异同点【转】

    相信数组是大家在编程最常使用的,不论任何语言都存在数组这样的数据结构,由于C#语言是完全面向对象的,所以在C#中的数组也是对象,实际上就是Array类的实例,Array类的使用可以说是使用最频繁的,只 ...

  4. SQL效率的几点心得

    这几天一直在写SQL,有时候对比同样效果的SQL语句,可是查询所需要的时间有时候相差很多,下面总结遇到的几个点: 1.between   and 在有些时候自己比较喜欢使用这个语句,因为可以通过把数据 ...

  5. [ios]scrollView实现移动与缩放

    实现滑动 1.在viewDidLoad中对scrollview的contentSize属性赋值 告诉他滑动范围. 实现缩放 1.在storyboard的scrollview的attribute标签中设 ...

  6. 十一、 BOOL类型、分支结构和关系运算符

    BOOL类型:表示非真即假.只有两个值:YES和NO,而二进制只识别二进制数,所以,将YES替换为“1”,NO替换为“0” BOOL数据类型占一字节的空间内存 BOOL数据类型输出为:%lu:输入为: ...

  7. Pomodairo,番茄工作法-应用篇

    传统:              选择一个待完成的任务              将番茄时间设为适合自己的固定时间              专注工作,中途不允许做任何与该任务无关的事,直到番茄时钟响 ...

  8. JDBC 学习笔记(四)—— 自定义JDBC框架+Apache—DBUtils框架+事务管理+操作多表

    本文目录:       1.自定义JDBC框架 ——数据库元数据:DataBaseMetaData        2.自定义JDBC框架 ——数据库元数据:DataBaseMetaData       ...

  9. 编译dubbo2.5.4时遇到的问题及解决

    dubbo的官方git地址为:https://github.com/alibaba/dubbo 按照其流程进行下载及编译,遇到的问题为: 1. 执行 mvn clean install -Dmaven ...

  10. 用MSBuild和Jenkins搭建持续集成环境 - 转

    http://www.infoq.com/cn/articles/MSBuild-1 http://www.infoq.com/cn/articles/MSBuild-2 MSBuild是在.NET ...