可以利用Graphics类的CopyFromScreen方法来实现屏幕截取,舍弃了比较麻烦的API函数,只要几句代码就能实现了,而且这个这个方法能实现只抓取部分区域的屏幕,可以实现类似qq抓屏的功能。
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
//获得当前屏幕的分辨率
Screen scr = Screen.PrimaryScreen;
Rectangle rc = scr.Bounds;
int iWidth = rc.Width;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//创建一个和屏幕一样大的Bitmap
Image myImage = new Bitmap(iWidth, iHeight);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//从一个继承自Image类的对象中创建Graphics对象
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//抓屏并拷贝到myimage里
g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(iWidth, iHeight));
//保存为文件
myImage.Save(@"c:/1.jpeg");
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//保存为文件
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
以上内容转自lijgame的blog,在此对作者表示感谢!
原文地址: http://blog.csdn.net/lijgame/archive/2006/12/18/1447921.aspx
现在就文中的“实现QQ截屏”功能继续研究如下。
1、首先要实现在屏幕上画图,即:可以在屏幕上画出一个矩形框,双击该矩形框将截取矩形框内的屏幕。
目前在屏幕上画图的C#实现代码如下:
[DllImport(
"
User32.dll
"
)]
public extern static System.IntPtr GetDC(System.IntPtr hWnd);
private void button19_Click( object sender, EventArgs e)
{
System.IntPtr DesktopHandle = GetDC(System.IntPtr.Zero);
Graphics g = Graphics.FromHdc(DesktopHandle);
g.DrawRectangle( new Pen(Color.Red), new Rectangle( 10 , 10 , 100 , 100 ));
}
public extern static System.IntPtr GetDC(System.IntPtr hWnd);
private void button19_Click( object sender, EventArgs e)
{
System.IntPtr DesktopHandle = GetDC(System.IntPtr.Zero);
Graphics g = Graphics.FromHdc(DesktopHandle);
g.DrawRectangle( new Pen(Color.Red), new Rectangle( 10 , 10 , 100 , 100 ));
}
需要用到可恶的API,实在不想用这种方法来实现!
2、研究出QQ屏幕上画图的真相
继续研究QQ截图的功能,发现当点击“截图”按钮之后,屏幕变成静止的了,原先网页上跳动的东西都不动了,哈哈,原因很简单,QQ截取了整个屏幕,然后用这张静止的屏幕覆盖全屏,真是精妙的解决办法啊!
于是用C#实现是:
建一个子窗体ScreenForm ,在窗体上放一个pictureBox和一个label控件。ScreenForm代码如下:
using
System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace copyScreen
{
public partial class ScreenForm : Form
{
public ScreenForm()
{
InitializeComponent();
}
public event copyToFatherTextBox copytoFather; // 截屏完毕后交个父窗体处理截图
public bool begin = false ; // 是否开始截屏
public bool isDoubleClick = false ;
public Point firstPoint = new Point( 0 , 0 ); // 鼠标第一点
public Point secondPoint = new Point( 0 , 0 ); // 鼠标第二点
public Image cachImage = null ; // 用来缓存截获的屏幕
public int halfWidth = 0 ; // 保存屏幕一半的宽度
public int halfHeight = 0 ; // 保存屏幕一般的高度
/* 复制整个屏幕,并让窗体填充屏幕 */
public void copyScreen()
{
Rectangle r = Screen.PrimaryScreen.Bounds;
Image img = new Bitmap(r.Width, r.Height);
Graphics g = Graphics.FromImage(img);
g.CopyFromScreen( new Point( 0 , 0 ), new Point( 0 , 0 ), r.Size);
// 窗体最大化,及相关处理
this .Width = r.Width;
this .Height = r.Height;
this .Left = 0 ;
this .Top = 0 ;
pictureBox1.Width = r.Width;
pictureBox1.Height = r.Height;
pictureBox1.BackgroundImage = img;
cachImage = img;
halfWidth = r.Width / 2 ;
halfHeight = r.Height / 2 ;
this .Cursor = new Cursor(GetType(), " MyCursor.cur " );
}
private void ScreenForm_Load( object sender, EventArgs e)
{
copyScreen();
}
/* 鼠标按下时开始截图 */
private void pictureBox1_MouseDown( object sender, MouseEventArgs e)
{
if ( ! isDoubleClick)
{
begin = true ;
firstPoint = new Point(e.X, e.Y);
changePoint(e.X, e.Y);
msg.Visible = true ;
}
}
/* 鼠标移动时显示截取区域的边框 */
private void pictureBox1_MouseMove( object sender, MouseEventArgs e)
{
if (begin)
{
// 获取新的右下角坐标
secondPoint = new Point(e.X, e.Y);
int minX = Math.Min(firstPoint.X, secondPoint.X);
int minY = Math.Min(firstPoint.Y, secondPoint.Y);
int maxX = Math.Max(firstPoint.X, secondPoint.X);
int maxY = Math.Max(firstPoint.Y, secondPoint.Y);
// 重新画背景图
Image tempimage = new Bitmap(cachImage);
Graphics g = Graphics.FromImage(tempimage);
// 画裁剪框
g.DrawRectangle( new Pen(Color.Red),minX,minY,maxX - minX,maxY - minY);
pictureBox1.Image = tempimage;
// 计算坐标信息
msg.Text = " 左上角坐标:( " + minX.ToString() + " , " + minY.ToString() + " )\r\n " ;
msg.Text += " 右下角坐标:( " + maxX.ToString() + " , " + maxY.ToString() + " )\r\n " ;
msg.Text += " 截图大小: " + (maxX - minX) + " × " + (maxY - minY) + " \r\n " ;
msg.Text += " 双击任意地方结束截屏! " ;
changePoint((minX + maxX) / 2 , (minY + maxY) / 2 );
}
}
/* 动态调整显示信息的位置,输入参数为当前截屏鼠标位置 */
public void changePoint( int x, int y)
{
if (x < halfWidth)
{
if (y < halfHeight)
{ msg.Top = halfHeight; msg.Left = halfWidth; }
else
{ msg.Top = 0 ; msg.Left = halfWidth; }
}
else
{
if (y < halfHeight)
{ msg.Top = halfHeight; msg.Left = 0 ; }
else
{ msg.Top = 0 ; msg.Left = 0 ; }
}
}
/* 鼠标放开时截图操作完成 */
private void pictureBox1_MouseUp( object sender, MouseEventArgs e)
{
begin = false ;
isDoubleClick = true ; // 之后再点击就是双击事件了
}
/* 双击时截图时,通知父窗体完成截图操作,同时关闭本窗体 */
private void pictureBox1_DoubleClick( object sender, EventArgs e)
{
if (firstPoint != secondPoint)
{
int minX = Math.Min(firstPoint.X, secondPoint.X);
int minY = Math.Min(firstPoint.Y, secondPoint.Y);
int maxX = Math.Max(firstPoint.X, secondPoint.X);
int maxY = Math.Max(firstPoint.Y, secondPoint.Y);
Rectangle r = new Rectangle(minX, minY, maxX - minX, maxY - minY);
copytoFather(r);
}
this .Close();
// msg.Text = r.ToString();
}
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace copyScreen
{
public partial class ScreenForm : Form
{
public ScreenForm()
{
InitializeComponent();
}
public event copyToFatherTextBox copytoFather; // 截屏完毕后交个父窗体处理截图
public bool begin = false ; // 是否开始截屏
public bool isDoubleClick = false ;
public Point firstPoint = new Point( 0 , 0 ); // 鼠标第一点
public Point secondPoint = new Point( 0 , 0 ); // 鼠标第二点
public Image cachImage = null ; // 用来缓存截获的屏幕
public int halfWidth = 0 ; // 保存屏幕一半的宽度
public int halfHeight = 0 ; // 保存屏幕一般的高度
/* 复制整个屏幕,并让窗体填充屏幕 */
public void copyScreen()
{
Rectangle r = Screen.PrimaryScreen.Bounds;
Image img = new Bitmap(r.Width, r.Height);
Graphics g = Graphics.FromImage(img);
g.CopyFromScreen( new Point( 0 , 0 ), new Point( 0 , 0 ), r.Size);
// 窗体最大化,及相关处理
this .Width = r.Width;
this .Height = r.Height;
this .Left = 0 ;
this .Top = 0 ;
pictureBox1.Width = r.Width;
pictureBox1.Height = r.Height;
pictureBox1.BackgroundImage = img;
cachImage = img;
halfWidth = r.Width / 2 ;
halfHeight = r.Height / 2 ;
this .Cursor = new Cursor(GetType(), " MyCursor.cur " );
}
private void ScreenForm_Load( object sender, EventArgs e)
{
copyScreen();
}
/* 鼠标按下时开始截图 */
private void pictureBox1_MouseDown( object sender, MouseEventArgs e)
{
if ( ! isDoubleClick)
{
begin = true ;
firstPoint = new Point(e.X, e.Y);
changePoint(e.X, e.Y);
msg.Visible = true ;
}
}
/* 鼠标移动时显示截取区域的边框 */
private void pictureBox1_MouseMove( object sender, MouseEventArgs e)
{
if (begin)
{
// 获取新的右下角坐标
secondPoint = new Point(e.X, e.Y);
int minX = Math.Min(firstPoint.X, secondPoint.X);
int minY = Math.Min(firstPoint.Y, secondPoint.Y);
int maxX = Math.Max(firstPoint.X, secondPoint.X);
int maxY = Math.Max(firstPoint.Y, secondPoint.Y);
// 重新画背景图
Image tempimage = new Bitmap(cachImage);
Graphics g = Graphics.FromImage(tempimage);
// 画裁剪框
g.DrawRectangle( new Pen(Color.Red),minX,minY,maxX - minX,maxY - minY);
pictureBox1.Image = tempimage;
// 计算坐标信息
msg.Text = " 左上角坐标:( " + minX.ToString() + " , " + minY.ToString() + " )\r\n " ;
msg.Text += " 右下角坐标:( " + maxX.ToString() + " , " + maxY.ToString() + " )\r\n " ;
msg.Text += " 截图大小: " + (maxX - minX) + " × " + (maxY - minY) + " \r\n " ;
msg.Text += " 双击任意地方结束截屏! " ;
changePoint((minX + maxX) / 2 , (minY + maxY) / 2 );
}
}
/* 动态调整显示信息的位置,输入参数为当前截屏鼠标位置 */
public void changePoint( int x, int y)
{
if (x < halfWidth)
{
if (y < halfHeight)
{ msg.Top = halfHeight; msg.Left = halfWidth; }
else
{ msg.Top = 0 ; msg.Left = halfWidth; }
}
else
{
if (y < halfHeight)
{ msg.Top = halfHeight; msg.Left = 0 ; }
else
{ msg.Top = 0 ; msg.Left = 0 ; }
}
}
/* 鼠标放开时截图操作完成 */
private void pictureBox1_MouseUp( object sender, MouseEventArgs e)
{
begin = false ;
isDoubleClick = true ; // 之后再点击就是双击事件了
}
/* 双击时截图时,通知父窗体完成截图操作,同时关闭本窗体 */
private void pictureBox1_DoubleClick( object sender, EventArgs e)
{
if (firstPoint != secondPoint)
{
int minX = Math.Min(firstPoint.X, secondPoint.X);
int minY = Math.Min(firstPoint.Y, secondPoint.Y);
int maxX = Math.Max(firstPoint.X, secondPoint.X);
int maxY = Math.Max(firstPoint.Y, secondPoint.Y);
Rectangle r = new Rectangle(minX, minY, maxX - minX, maxY - minY);
copytoFather(r);
}
this .Close();
// msg.Text = r.ToString();
}
}
}
界面如下:
![](https://i-blog.csdnimg.cn/blog_migrate/47357283e4a71d13925a509f8f6b0e6c.jpeg)
本程序下载: CODE 演示版: Demo