using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace LC
{
class ScreenCapture
{
#region 抓取屏幕
/// <summary>
/// 抓取屏幕(层叠的窗口)
/// </summary>
/// <param name="x">左上角的横坐标</param>
/// <param name="y">左上角的纵坐标</param>
/// <param name="width">抓取宽度</param>
/// <param name="height">抓取高度</param>
/// <returns></returns>
public static Bitmap captureScreen(int x, int y, int width, int height)
{
Bitmap bmp = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(new Point(x, y), new Point(0, 0), bmp.Size);
g.Dispose();
}
//bit.Save(@"capture2.png");
return bmp;
}

/// <summary>
/// 抓取整个屏幕
/// </summary>
/// <returns></returns>
public static Bitmap captureScreen()
{
Size screenSize = Screen.PrimaryScreen.Bounds.Size;
return captureScreen(0,0,screenSize.Width,screenSize.Height);
}
#endregion

#region 使用BitBlt方法抓取控件,无论控件是否被遮挡
/// <summary>
/// 控件(窗口)的截图,控件被其他窗口(而非本窗口内控件)遮挡时也可以正确截图,使用BitBlt方法
/// </summary>
/// <param name="control">需要被截图的控件</param>
/// <returns>该控件的截图,控件被遮挡时也可以正确截图</returns>
public static Bitmap captureControl(Control control)
{
//调用API截屏
IntPtr hSrce = GetWindowDC(control.Handle);
IntPtr hDest = CreateCompatibleDC(hSrce);
IntPtr hBmp = CreateCompatibleBitmap(hSrce, control.Width, control.Height);
IntPtr hOldBmp = SelectObject(hDest, hBmp);
if (BitBlt(hDest, 0, 0, control.Width, control.Height, hSrce, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt))
{
Bitmap bmp = Image.FromHbitmap(hBmp);
SelectObject(hDest, hOldBmp);
DeleteObject(hBmp);
DeleteDC(hDest);
ReleaseDC(control.Handle, hSrce);
// bmp.Save(@"a.png");
// bmp.Dispose();
return bmp;
}
return null;

}

// /// <summary>
// /// 有问题!!!!!用户区域坐标不对啊
// /// 控件(窗口)的用户区域截图,控件被其他窗口(而非本窗口内控件)遮挡时也可以正确截图,使用BitBlt方法
// /// </summary>
// /// <param name="control">需要被截图的控件</param>
// /// <returns>控件(窗口)的用户区域截图</returns>
// public static Bitmap captureClientArea(Control control)
// {
//
// Size sz = control.Size;
// Rectangle rect = control.ClientRectangle;
//
//
// //调用API截屏
// IntPtr hSrce = GetWindowDC(control.Handle);
// IntPtr hDest = CreateCompatibleDC(hSrce);
// IntPtr hBmp = CreateCompatibleBitmap(hSrce, rect.Width, rect.Height);
// IntPtr hOldBmp = SelectObject(hDest, hBmp);
// if (BitBlt(hDest, 0, 0, rect.Width, rect.Height, hSrce, rect.X, rect.Y, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt))
// {
// Bitmap bmp = Image.FromHbitmap(hBmp);
// SelectObject(hDest, hOldBmp);
// DeleteObject(hBmp);
// DeleteDC(hDest);
// ReleaseDC(control.Handle, hSrce);
// // bmp.Save(@"a.png");
// // bmp.Dispose();
// return bmp;
// }
// return null;
//
// }
#endregion

#region 使用PrintWindow方法抓取窗口,无论控件是否被遮挡
/// <summary>
/// 窗口的截图,窗口被遮挡时也可以正确截图,使用PrintWindow方法
/// </summary>
/// <param name="control">需要被截图的窗口</param>
/// <returns>窗口的截图,控件被遮挡时也可以正确截图</returns>
public static Bitmap captureWindowUsingPrintWindow(Form form)
{
return GetWindow(form.Handle);
}

private static Bitmap GetWindow(IntPtr hWnd)
{
IntPtr hscrdc = GetWindowDC(hWnd);
Control control = Control.FromHandle(hWnd);
IntPtr hbitmap = CreateCompatibleBitmap(hscrdc, control.Width, control.Height);
IntPtr hmemdc = CreateCompatibleDC(hscrdc);
SelectObject(hmemdc, hbitmap);
PrintWindow(hWnd, hmemdc, 0);
Bitmap bmp = Bitmap.FromHbitmap(hbitmap);
DeleteDC(hscrdc);//删除用过的对象
DeleteDC(hmemdc);//删除用过的对象
return bmp;
}
#endregion

#region DLL calls
[DllImport("gdi32.dll")]
static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int
wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, CopyPixelOperation rop);
[DllImport("gdi32.dll")]
static extern IntPtr DeleteDC(IntPtr hDc);
[DllImport("gdi32.dll")]
static extern IntPtr DeleteObject(IntPtr hDc);
[DllImport("gdi32.dll")]
static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
[DllImport("gdi32.dll")]
static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll")]
static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);
[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr ptr);
[DllImport("user32.dll")]
public static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, UInt32 nFlags);
[DllImport("user32.dll")]
static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc);
#endregion
}
}

c#截屏功能的实现的更多相关文章

  1. PhantomJS linux系统下安装步骤及使用方法(网页截屏功能)

    PhantomJS 是一个基于 WebKit 的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, CSS 选择器, JSON, ...

  2. Atitit截屏功能的设计解决方案

    Atitit截屏功能的设计解决方案 自己实现.... 使用快捷键.. 弹出自己的win,,背景是屏幕快照 点击鼠标光标变成十字状态 出现截屏窗口调整截屏窗口位置与大小 释放鼠标,三个btn,,  复制 ...

  3. android4.3 截屏功能的尝试与失败分析

    1.背景 上一篇讲了在源码中捕获到了android手机的截屏函数(同时按下电源键与音量减,详情http://blog.csdn.net/buptgshengod/article/details/199 ...

  4. iOS截屏功能

    代码: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. // ...

  5. 使用laravel框架与phantomjs实现截屏功能

    在网上看到的关于phantomjs实现截屏功能很多都是与node结合在一起使用,并需要输入命令才能执行.因此我想要实现输入网址即可截屏并输出图片的功能.示例:http://120.77.171.182 ...

  6. Android自己定义截屏功能,相似QQ截屏

    由于公司业务需求 须要对一个屏幕进行截屏.但自带的截屏功能是远远不够项目的功能需求 ,我们是做一个画板软件 .须要的像QQ那样截屏之后 ,能够看到我们自己定义的工具.有画笔,button等等 .and ...

  7. 【玩转cocos2d-x之三十九】Cocos2d-x 3.0截屏功能集成

    3.0的截屏和2.x的截屏基本上同样.都是利用RenderTexture来处理,在渲染之前调用call函数,然后调用Cocos的场景visit函数对其进行渲染,渲染结束后调用end函数就可以.仅仅是3 ...

  8. [置顶] Android 应用内禁止截屏功能的实现

    截图介绍   Android的调试工具DDMS提供有截屏功能,很多软件也会有截屏功能,在做支付等安全类应用的时候,为了保证用户的资产和系统安全,往往会禁止应用内截屏,禁止之后,在此应用处于前台的情况下 ...

  9. 小胖说事22-----iOS开发技巧之取消键盘响应和截屏功能

    1.UILable内容模糊 在非Retina的iPad mini 的屏幕上,一个UILable的frame的origin值假设是有小数位(如0.5),就会造成显示模糊,所以不妨用整数值的origin. ...

  10. c# wpf 利用截屏键实现截屏功能

    原文:c# wpf 利用截屏键实现截屏功能     最近做一个wpf程序需要截图功能,查找资料费了一些曲折,跟大家分享一下.     先是找到了这样一份代码:     static class Scr ...

随机推荐

  1. Lucene的例子

    lucene爬数据库中的数据无非也是查询数据.所有我们用lucene搜索数据主要有下面几个步骤:(代码紧供参考)       一  ,  从数据库中查数据 ====爬数据  ------------- ...

  2. 八数码难题 双向搜索(codevs 1225)

    题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.问题描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字 ...

  3. [CodePlus2017]汀博尔

    Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 158  Solved: 61[Submit][Status][Discuss] Description ...

  4. Java jsp页面中jstl标签详解

    JSLT标签库,是日常开发经常使用的,也是众多标签中性能最好的.把常用的内容,放在这里备份一份,随用随查.尽量做到不用查,就可以随手就可以写出来.这算是Java程序员的基本功吧,一定要扎实. JSTL ...

  5. EsAlert

    https://www.cnblogs.com/zhaishaomin/p/7417306.html https://blog.csdn.net/pujiaolin/article/details/5 ...

  6. Codeforces 659F Polycarp and Hay【BFS】

    有毒,自从上次选拔赛(哭哭)一个垃圾bfs写错之后,每次写bfs都要WA几发...好吧,其实也就这一次... 小白说的对,还是代码能力不足... 非常不足... 题目链接: http://codefo ...

  7. 转: 关于Linux常用的二进制文件分析方法

    当你在unix下拿到一个二进制文件但不知道它是什么的时候,可以通过以下方法得到一此提示 1. 最首先应该尝试strings命令,比如拿到一个叫cr1的二进制文件,可以: $ strings cr1 | ...

  8. SHELL脚本实现分区

    写一个脚本(前提:请为虚拟机新增一块硬盘,架设它为/dev/sdb),为指定的硬盘创建分区 1,列出当前系统上所有的磁盘,让用户选择,如果选择quit则退出脚本:如果用户选择错误,就让用户重新选择 2 ...

  9. Spring的@Autowired注解

    以下内容引用自http://wiki.jikexueyuan.com/project/spring/annotation-based-configuration/spring-autowired-an ...

  10. 关键字检索高亮标出-javasript/jQuery代码实现

    原文:http://www.open-open.com/code/view/1454504432089 此方法传入2个参数,一个是被检索内容所在的表单或者HTML元素的ID,另一为关键字,多个关键字的 ...