转自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#中声明此函数:

[ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
private static extern bool BitBlt (
IntPtr hdcDest , // 目标 DC的句柄
int nXDest ,
int nYDest ,
int nWidth ,
int nHeight ,
IntPtr hdcSrc , // 源DC的句柄
int nXSrc ,
int nYSrc ,
System.Int32 dwRop // 光栅的处理数值
) ;

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

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

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

Graphics g1 = this.CreateGraphics ( ) ;

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

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

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

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

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

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

  1. 获取屏幕像素:    

 SystemParameters.FullPrimaryScreenHeight
SystemParameters.FullPrimaryScreenWidth

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

 SystemParameters.WorkArea.Height
SystemParameters.WorkArea.Width

C# 获得屏幕大小

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

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

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

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

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

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

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

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

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

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

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

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

using System ;
using System.Drawing ;
using System.Collections ;
using System.ComponentModel ;
using System.Windows.Forms ;
using System.Data ;
using System.Drawing.Imaging ;
public class Form1 : Form.
{
private Button button1 ;
private System.ComponentModel.Container components = null ; public Form1 ( )
{
//初始化窗体中的各个组件
InitializeComponent ( ) ;
}
// 清除程序中使用过的资源
protected override void Dispose ( bool disposing )
{
if ( disposing )
{
if ( components != null )
{
components.Dispose ( ) ;
}
}
base.Dispose ( disposing ) ;
}
private void InitializeComponent ( )
{
button1 = new Button ( );
SuspendLayout ( ) ;
button1.Location = new System.Drawing.Point ( , ) ;
button1.Name = "button1" ;
button1.Size = new System.Drawing.Size ( , ) ;
button1.TabIndex = ;
button1.Text = "捕获" ;
button1.Click += new System.EventHandler ( button1_Click ) ; AutoScaleBaseSize = new System.Drawing.Size ( , ) ;
ClientSize = new System.Drawing.Size ( , ) ;
Controls.Add ( button1 ) ;
MaximizeBox = false ;
MinimizeBox = false ;
Name = "Form1" ;
Text = "C#捕获当前屏幕!" ;
ResumeLayout ( false ) ; }
//声明一个API函数
[ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
private static extern bool BitBlt (
IntPtr hdcDest , // 目标 DC的句柄
int nXDest ,
int nYDest ,
int nWidth ,
int nHeight ,
IntPtr hdcSrc , // 源DC的句柄
int nXSrc ,
int nYSrc ,
System.Int32 dwRop // 光栅的处理数值
) ; static void Main ( )
{
Application.Run ( new Form1 ( ) ) ;
}
private void button1_Click ( object sender , System.EventArgs e )
{
//获得当前屏幕的大小
Rectangle rect = new Rectangle ( ) ;
rect = Screen.GetWorkingArea ( this ) ;
//创建一个以当前屏幕为模板的图象
Graphics g1 = this.CreateGraphics ( ) ;
//创建以屏幕大小为标准的位图
Image MyImage = new Bitmap ( rect.Width , rect.Height , g1 ) ;
Graphics g2 = Graphics.FromImage ( MyImage ) ;
//得到屏幕的DC
IntPtr dc1 = g1.GetHdc ( ) ;
//得到Bitmap的DC
IntPtr dc2 = g2.GetHdc ( ) ;
//调用此API函数,实现屏幕捕获
BitBlt ( dc2 , , , rect.Width , rect.Height , dc1 , , , ) ;
//释放掉屏幕的DC
g1.ReleaseHdc ( dc1 ) ;
//释放掉Bitmap的DC
g2.ReleaseHdc ( dc2 ) ;
//以JPG文件格式来保存
MyImage.Save ( @"c:Capture.jpg" , ImageFormat.Jpeg );
MessageBox.Show ( "当前屏幕已经保存为C盘的capture.jpg文件!" ) ;
}
}

[转]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. 51nod 1021 石头归并

    1021 石子归并 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合 ...

  2. php学习日志(4)-The mbstring extension is missing. Please check your PHP configuration错误及解决方法

    在安装好wampServer后,一直没有使用phpMyAdmin,今天用了一下,phpMyAdmin显示错误:The mbstring extension is missing. Please che ...

  3. 为什么24位位图(真彩色)的biSizeImage不等于(biWidth*biBitCount+31)/32*4*biHeight?

    规定的,规定BMP文件的像素数据是按行存储的,而且每行的字节数必须为4的倍数,如果实际的像素数据不是4的倍数咋办?这就需要字节对齐,对齐是在一行的末尾添0以补足一行的字节数为4的倍数, ( biWid ...

  4. 浅析IList与List的区别

    List和IList是.net开发中经常遇到的两种类型,用法上经常会让初学者摸不到头脑,下面简要的分析一下这两种类型的区别 1.IList<T>是接口,继承自ICollection< ...

  5. 深入剖析——float之个人见解

    浮动的原本作用仅仅是为了实现文字的环绕效果. 以下分别是html与css代码,显示效果如下图.因为两个div使用了float浮动属性,所以脱离了标准文档流.让父元素撑开高度,我们需要清除浮动. < ...

  6. 表达式语言之EL表达式

    1.EL的用法EL的起源:起源于JSTL.EL运算符: 算术型:+.-.*./.div.%.mod.其中/和div都表示求除.%和mod表示求余数. 逻辑型:and或&&.or或||. ...

  7. 如何设置让SFTP的用户限制在某个目录下

    通常SFTP的任何用户登录之后能看到整个系统的文件目录,这样很不安全. 通过chroot我们可以将某个用户登录SFTP后只能在某个限定的目录下操作,这样可以更安全.我们来看看怎么设置. 1.创建一个用 ...

  8. iOS 进阶 第十三天(0414)

    0414 画线.圆和圆弧的第二种方法 5中方法画矩形: 第二种画图形的方法: 之前做的方法都是先把要画的元素缓存到图形上下文CGConteextRef中去,现在第二种方法也缓存到CGPath中去.其实 ...

  9. Error: Most middleware (like bodyParser) ...

    运行NodeJS时出现如下错误: Error: Most middleware (like bodyParser) is no longer bundled with Express and must ...

  10. 【转载】Hadoop历史服务器详解

    免责声明:     本文转自网络文章,转载此文章仅为个人收藏,分享知识,如有侵权,请联系博主进行删除.     原文作者:过往记忆(http://www.iteblog.com/)     原文地址: ...