基于GDI和D3D的抓屏技术
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices; namespace DataFrameFetch
{
public class WinGdi32Api
{
[DllImport("GDI32.dll")]
public static extern bool BitBlt(int hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, int hdcSrc, int nXSrc, int nYSrc, int dwRop);
[DllImport("GDI32.dll")]
public static extern int CreateCompatibleBitmap(int hdc, int nWidth, int nHeight);
[DllImport("GDI32.dll")]
public static extern int CreateCompatibleDC(int hdc);
[DllImport("GDI32.dll")]
public static extern bool DeleteDC(int hdc);
[DllImport("GDI32.dll")]
public static extern bool DeleteObject(int hObject);
[DllImport("GDI32.dll")]
public static extern int GetDeviceCaps(int hdc, int nIndex);
[DllImport("GDI32.dll")]
public static extern int SelectObject(int hdc, int hgdiobj);
[DllImport("User32.dll")]
public static extern int GetDesktopWindow();
[DllImport("User32.dll")]
public static extern int GetWindowDC(int hWnd);
[DllImport("User32.dll")]
public static extern int GetDC(int hWnd);
[DllImport("User32.dll")]
public static extern int ReleaseDC(int hWnd, int hDC);
}
} using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO; namespace DataFrameFetch
{
public class DataFetch
{ public DataFetch()
{ } /// <summary>
/// 全屏截图
/// </summary>
/// <returns></returns>
public Bitmap CaptureScreen()
{
DateTime dt_start = DateTime.Now;
int source = WinGdi32Api.GetWindowDC(WinGdi32Api.GetDesktopWindow());
int bitmap = WinGdi32Api.CreateCompatibleBitmap(source, WinGdi32Api.GetDeviceCaps(source, 8), WinGdi32Api.GetDeviceCaps(source, 10)); int destination = WinGdi32Api.CreateCompatibleDC(source);
WinGdi32Api.SelectObject(destination, bitmap);
WinGdi32Api.BitBlt(destination, 0, 0, WinGdi32Api.GetDeviceCaps(source, 8), WinGdi32Api.GetDeviceCaps(source, 10), source, 0, 0, 0x00CC0020);
Bitmap img = this.GetBitmap(bitmap);
this.Cleanup(bitmap, source, destination);
DateTime dt_end = DateTime.Now;
TimeSpan ts = dt_end - dt_start;
System.Diagnostics.Debug.WriteLine(ts.Milliseconds.ToString());
return img;
} public Bitmap CaptureScreen(Control control)
{
DateTime dt_start = DateTime.Now; int source = WinGdi32Api.GetDC(control.Handle.ToInt32());
int bitmap = WinGdi32Api.CreateCompatibleBitmap(source, control.Width,control.Height); int destination = WinGdi32Api.CreateCompatibleDC(source);
WinGdi32Api.SelectObject(destination, bitmap);
WinGdi32Api.BitBlt(destination, 0, 0, control.Width, control.Height, source, 0, 0, 0x00CC0020);
Bitmap img = this.GetBitmap(bitmap);
this.Cleanup(bitmap, source, destination); byte[] buffer = this.ConvertBitmapToRGBByteArray(img); string filename = "F:\\img\\" + dt_start.ToString("yyyyMMddHHmmss") + dt_start.Millisecond.ToString(); FileStream fs = new FileStream(filename + ".olc", FileMode.Create);
fs.Write(buffer, 0, buffer.Length);
fs.Flush();
fs.Close(); //Bitmap bmp = this.FromRGB(buffer, img.Width, img.Height);
//bmp.Save(filename + "_1.bmp"); DateTime dt_end = DateTime.Now;
TimeSpan ts = dt_end - dt_start;
System.Diagnostics.Debug.WriteLine(ts.Milliseconds.ToString());
return img;
} private void Cleanup(int bitmap, int source, int destination)
{
WinGdi32Api.ReleaseDC(WinGdi32Api.GetDesktopWindow(), source);
WinGdi32Api.DeleteDC(destination);
WinGdi32Api.DeleteObject(bitmap);
} private Bitmap GetBitmap(int hbitmap)
{
Bitmap bmp = new Bitmap(Image.FromHbitmap(new IntPtr(hbitmap)), Image.FromHbitmap(new IntPtr(hbitmap)).Width, Image.FromHbitmap(new IntPtr(hbitmap)).Height);
return bmp;
} /// <summary>
/// 将位图转换成数组
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
private byte[] ConvertBitmapToRGBByteArray(Bitmap bmp)
{
Rectangle rect = new Rectangle(new Point(0,0),bmp.Size);
BitmapData bmpdata = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); int len = bmp.Width * bmp.Height * 3;
byte[] buffer = new byte[len];
int index = 0;
unsafe
{
byte* color = (byte*)bmpdata.Scan0;
for (int y = 0; y < bmp.Height; y++)
{
for (int x = 0; x < bmp.Width; x++)
{
buffer[index++] = *color;
buffer[index++] = *(color + 1);
buffer[index++] = *(color + 2);
color += 3;
}
//color += bmpdata.Stride - bmpdata.Width * 3;
}
}
bmp.UnlockBits(bmpdata);
return buffer;
} /// <summary>
/// 图像象素数组转成位图
/// </summary>
/// <param name="buffer"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <returns></returns>
public Bitmap ConvertRGBByteArrayToBitmap(byte[] buffer, int width, int height)
{
// 申请目标位图的变量,并将其内存区域锁定
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);//创建新图像
Rectangle rect = new Rectangle(0, 0, width, height);
BitmapData bmpData = bmp.LockBits(rect,ImageLockMode.WriteOnly,PixelFormat.Format24bppRgb);
//// 用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中
Marshal.Copy(buffer, 0, bmpData.Scan0, buffer.Length);
bmp.UnlockBits(bmpData); // 解锁内存区域
return bmp;
}
}
}
方法二以VC++实现
BOOL ScreenShot(HWND hWnd, TCHAR* fileName) { HRESULT hr; IDirect3D9* gpD3D=NULL; IDirect3DDevice9* gpd3dDevice=NULL; IDirect3DSurface9* gpSurface=NULL; D3DDISPLAYMODE ddm; D3DPRESENT_PARAMETERS d3dpp; if((gpD3D=Direct3DCreate9(D3D_SDK_VERSION))==NULL) { ErrorMessage("Unable to Create Direct3D "); return E_FAIL; } if(FAILED(gpD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&ddm))) { ErrorMessage("Unable to Get Adapter Display Mode"); return E_FAIL; } ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS)); d3dpp.Windowed=WINDOW_MODE; d3dpp.Flags=D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; d3dpp.BackBufferFormat=ddm.Format; d3dpp.BackBufferHeight=nDisplayHeight=gScreenRect.bottom =ddm.Height; d3dpp.BackBufferWidth=nDisplayWidth=gScreenRect.right =ddm.Width; d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE; d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow=hWnd; d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_DEFAULT; d3dpp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT; if(FAILED(gpD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING ,&d3dpp,&gpd3dDevice))) { ErrorMessage("Unable to Create Device"); return E_FAIL; } if(FAILED(gpd3dDevice->CreateOffscreenPlainSurface(ddm.Width, ddm.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &gpSurface, NULL))) { ErrorMessage("Unable to Create Surface"); return E_FAIL; } if (FAILED(hr = gpd3dDevice->GetFrontBufferData(0, gpSurface))) { gpSurface->Release() ; return hr ; } hr = D3DXSaveSurfaceToFile(fileName, D3DXIFF_BMP, gpSurface, NULL, NULL); gpSurface->Release() ; return hr ; }
基于GDI和D3D的抓屏技术的更多相关文章
- Windows桌面共享中一些常见的抓屏技术
1. BitBlt 我想做Windows开发应该都知道这个API, 它能实现DC间的内容拷贝, 如果我们把源DC指定成Monitor DC或是桌面DC, 它就能实现抓屏功能. 对于通过这种方式的抓屏, ...
- Windows抓屏技术
Windows桌面共享中一些常见的抓屏技术 1. BitBlt 我想做Windows开发应该都知道这个API, 它能实现DC间的内容拷贝, 如果我们把源DC指定成Monitor DC或是桌面DC, ...
- 基于MirrorDriver的录屏技术
计算机屏幕图像的截取在屏幕的录制.计算机远程控制以及多媒体教学软件中都是关键术,基于Windows操作系统有多种截屏方法,研究的重点集中在如何快速有效的截取DBI(Device-Independent ...
- 基于Casperjs的网页抓取技术【抓取豆瓣信息网络爬虫实战示例】
CasperJS is a navigation scripting & testing utility for the PhantomJS (WebKit) and SlimerJS (Ge ...
- DXGI快速截屏录屏技术
DXGI快速截屏录屏技术 概述 很多地方都需要用到截屏/录屏技术,比如桌面直播,桌面录制等等.在微软Windows平台,有很多截屏的接口,不过大多数性能并不理想,Windows8以后微软引入了一套 ...
- 解析电子墨水屏技术(工作原理与LCD的区别)【转】
转自:https://blog.csdn.net/weixin_42509369/article/details/84646808 阅读电子书早已成为大家生活中一部分,方便轻巧的电子版书籍更便于携带, ...
- ffmpeg抓屏输出的设置
之前做windows下抓屏输出时使用ffmpeg.exe作为抓屏输出测试,命令行如下: ffmpeg -f gdigrab -i "desktop" -r 25 -vcodec m ...
- QQ群排名霸屏技术居然是这样简单
最近做了一些收费的QQ群,收多少钱,一块钱的入门费,也就是说进入我的QQ群必须要1块钱的会费. 我的QQ群主要是干嘛呢,放些电影,比如说市面上电影院,正在播放的,最新最热门的,火爆的一些电影. 先前呢 ...
- 方别《QQ群霸屏技术》,又见《QQ群建群细则》
规则,时刻变动;QQ群系列,咱们再来一轮. QQ群霸屏技术,你说建群貌似很菜,大家仿佛都知道,其实只知其一不知其二. QQ群类别 群分类,常规的就以下几种. 普通群. 建群随意,偏个性化,一言不合就拉 ...
随机推荐
- 超图GIS入门iserver搭建,前端调用iserver加载三维场景demo
目录 前言 一.GIS介绍,为什么选择它? 二.环境安装 三.调用三维GIS场景 设置地图风格 添加地图iServer服务 前言 前段时间因为对3D制图感兴趣,学习了一下国内制作GIS的公司产品技术, ...
- Kruskal 重构树小记
其实也不是多难的知识点吧--学了一个中午+半个下午就把它学会了(做过那道 jxd 作业 CF571D 的应该比较好理解) Kruskal 重构树大概就是在正常 Kruskal 的时候,对于两个需要连边 ...
- Java设计模式之(十四)——策略模式
1.什么是策略模式? Define a family of algorithms, encapsulate each one, and make them interchangeable. Strat ...
- Linux 安装和使用 RAR工具
RAR 安装 方法一.通过apt命令安装 rar 和 unrar 未安装 unrar 的情况下,提取 RAR 文件会报出"未能提取"错误 Ubuntu 安装 rar和 unrar( ...
- expr计算字符串长度
命令:expr length "quanzhiqinag" #!/bin/bash for N in quan zhi qiang do if [ `expr length $N ...
- 【模板】滑动窗口最值(单调队列)/洛谷P1886
题目链接 https://www.luogu.com.cn/problem/P1886 题目大意 有一个长为 \(n\) 的序列 \(a\) ,以及一个大小为 \(k\) 的窗口.现在这个从左边开始向 ...
- Hadoop入门 集群崩溃的处理方法
目录 集群崩溃的处理方法 搞崩集群 错误示范 正确处理方法 1 回到hadoop的家目录 2 杀死进程 3 删除每个集群的data和logs 4 格式化 5 启动集群 总结 原因分析 集群崩溃的处理方 ...
- day16 Linux三剑客之awk
day16 Linux三剑客之awk 1.什么是awk,主要作用是什么? 什么是awk,主要作用是什么? awk 主要用来处理文件,将文本按照指定的格式输出.其中包含变量,循环以及数组. 2.awk的 ...
- python web工程师跳巢攻略
python web工程师跳巢攻略 流程 一面问基础 二面问项目 三面问设计(经验) web请求的流程 浏览器 负载均衡 web框架 业务逻辑 数据库缓存 后端技术栈 python语言基础 语言特点 ...
- 大数据学习day32-----spark12-----1. sparkstreaming(1.1简介,1.2 sparkstreaming入门程序(统计单词个数,updateStageByKey的用法,1.3 SparkStreaming整合Kafka,1.4 SparkStreaming获取KafkaRDD的偏移量,并将偏移量写入kafka中)
1. Spark Streaming 1.1 简介(来源:spark官网介绍) Spark Streaming是Spark Core API的扩展,其是支持可伸缩.高吞吐量.容错的实时数据流处理.Sp ...