转自:http://blog.163.com/maosth@126/blog/static/1350684352009112025953404/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Da
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
namespace zhuaScreen
{
public partial class Form1 :Form
{
publicForm1()
{
InitializeComponent();
}
[System.Runtime.InteropServices.DllImp
privatestatic extern bool BitBlt(
IntPtrhdcDest, //目的DC的句柄
intnXDest, //目的图形的左上角的x坐标
intnYDest, //目的图形的左上角的y坐标
intnWidth, //目的图形的矩形宽度
intnHeight, //目的图形的矩形高度
IntPtrhdcSrc, //源DC的句柄
intnXSrc, //源图形的左上角的x坐标
intnYSrc, //源图形的左上角的x坐标
System.Int32 dwRop //光栅操作代码
);
privatevoid button1_Click(object sender, EventArgs e)
{
Graphics g1 =this.CreateGraphics(); //获得窗体图形对象
Image MyImage = new Bitmap(this.ClientRectangle.Width,this.ClientRectangle.Height, g1);
Graphics g2 =Graphics.FromImage(MyImage); //创建位图图形对象
IntPtr dc1 =g1.GetHdc(); //获得窗体的上下文设备
IntPtr dc2 =g2.GetHdc(); //获得位图文件的上下文设备
BitBlt(dc2, 0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height, dc1,0, 0, 13369376);//写入到位图
g1.ReleaseHdc(dc1); //释放窗体的上下文设备
g2.ReleaseHdc(dc2); //释放位图文件的上下文设备
MyImage.Save("Captured.jpg",ImageFormat.Jpeg); //保存为jpeg文件
MessageBox.Show("保存图片在同目录下结束!");
}
}
}
居然只能把本程序自己的界面截下,我要的是把屏幕截下来,不过有总比没有好,正好我也不知道怎么截自己,先放着.后来又发现了一个截屏的程序:
是在上面修改,其他不变
private voidbutton1_Click(object sender, 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);
IntPtr dc1 = g1.GetHdc(); //得到屏幕的DC
IntPtr dc2 =g2.GetHdc(); //得到Bitmap的DC
BitBlt(dc2, 0, 0, rect.Width, rect.Height, dc1, 0, 0,13369376); //调用此API函数,实现屏幕捕获
g1.ReleaseHdc(dc1); //释放掉屏幕的DC
g2.ReleaseHdc(dc2); //释放掉Bitmap的DC
MyImage.Save("Capture.jpg",ImageFormat.Jpeg); //以JPG文件格式来保存
MessageBox.Show("当前屏幕已经保存为capture.jpg文件!");
}
可是,我多试几下发现这个程序有点问题,只能截自己左上的开始的一个屏幕大小的图片所以右下脚是黑的.我把程序Form启动的位置设在右上脚,不就可以把整个屏幕截下来吗?暂时勉强算是解决了问题.至于代码,当时的我还只能旁观.
再后来我在一本C#例题书上又碰到回这个问题.我还没想好怎么解决上面的问题就眼睁睁的看着别人帮忙给搞定了.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Da
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace 图形图象
{
public partial class ScreenCapture : Form
{
public ScreenCapture()
{
InitializeComponent();
}
private void btn_Capture_Click(object sender, EventArgs e)
{
pictureBox1.Image = DeskTopCapture.Capture();
pictureBox1.Size = pictureBox1.Size;
pictureBox1.Image.Save("Capture.jpg", ImageFormat.Jpeg);
MessageBox.Show("当前屏幕已经保存为capture.jpg文件!");
}
}
public class DeskTopCapture
{
[DllImp
private extern static IntPtrGetDesktopWindow();
[DllImp
private extern static IntPtrGetDC(IntPtr windowHandle);
[DllImp
private extern static IntPtrGetCurrentObject(IntPtr hdc, ushort objectType);
[DllImp
private extern static voidReleaseDC(IntPtr hdc);
const int OBJ_BITMAP = 7;
public static Bitmap Capture()
{
//获得桌面窗口的上下文
IntPtrdesktopWindow =GetDesktopWindow();
IntPtr desktopDC= GetDC(desktopWindow);
//得到image的GDI句柄
IntPtrdesktopBitmap = GetCurrentObject(desktopDC, OBJ_BITMAP);
//用句柄创建一个.NET图形对象
BitmapdesktopImage = Image.FromHbitmap(desktopBitmap);
//释放设备上下文
//ReleaseDC(desktopDC);
returndesktopImage;
}
}
}
当时发现自己能看懂它了,这也算阶段性的进步吧!这个程序明显比上面两个更科学的完成了截屏的使命!昨天,我看见一篇文章上不用API截http://hi.baidu.com/goga/blog/item/a682b2192bad2e4342a9ad2c.html虽然我最终也没明白过来他是怎么实现的不过唤醒了我不用API截屏的意念.早上起来搜了下Screen类:
C#中对系统的桌面进行了封装,即Screen类,其中的重要属性包括显示的边界Bounds、系统上所有显示器的数组AllScreens、显示器的工作区WorkingArea等。.NET Framework 2.0中新增加了获得windows桌面的方法:Graphics.CopyFromScreen。该方法已重载,有多种调用格式。例如:
public void CopyFromScreen (
Point upperLeftSource, //源矩形左上角的点
Point upperLeftDestination, //目标矩形左上角的点
Size blockRegionSize) //要传输的区域大小
后来,就有了下面的截屏程序:
usingSystem;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace不用API截屏
{
class Program
{
static void Main(string[] args)
{
Image myImg= new Bitmap(Screen.AllScreens[0].Bounds.Width,Screen.AllScreens[0].Bounds.Height);
Graphics g =Graphics.FromImage(myImg);
g.CopyFromScreen(new Point(0, 0), new Point(0,0),Screen.AllScreens[0].Bounds.Size);
myImg.Save("Capture.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}
因为一时的冲动,想不用什么Form直接来个控制台程序快些.结果才意识到每次截屏,结果都会有个黑窗体.那时大名鼎鼎的Console,隐藏起来还真不容易啊!所以建议还是用WindowApplication在Form1_load事件里把屏幕给截了就会得到原始的屏幕了.
usingSystem;
using System.Collections.Generic;
using System.ComponentModel;
using System.Da
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace不用API截屏
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Image myImg= new Bitmap(Screen.AllScreens[0].Bounds.Width,Screen.AllScreens[0].Bounds.Height);
Graphics g =Graphics.FromImage(myImg);
g.CopyFromScreen(new Point(0, 0), new Point(0, 0),Screen.AllScreens[0].Bounds.Size);
myImg.Save("Capture.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}