博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Delphi中使用DirectX截屏函数
阅读量:4519 次
发布时间:2019-06-08

本文共 5402 字,大约阅读时间需要 18 分钟。

procedure CaptureScreen(Const FileName: string);var  BitsPerPixel: Byte;  pD3D: IDirect3D9;  pSurface: IDirect3DSurface9;  g_pD3DDevice: IDirect3DDevice9;  D3DPP: TD3DPresentParameters;  ARect: TRect;  LockedRect: TD3DLockedRect;  BMP: TBitmap;  i, p: Integer;begin  BitsPerPixel := GetDeviceCaps(Canvas.Handle, BITSPIXEL);  FillChar(d3dpp, SizeOf(d3dpp), 0);  D3DPP.Windowed := True;  D3DPP.Flags := D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;  D3DPP.SwapEffect := D3DSWAPEFFECT_DISCARD;  D3DPP.BackBufferWidth := Screen.Width;  D3DPP.BackBufferHeight := Screen.Height;  D3DPP.BackBufferFormat := D3DFMT_X8R8G8B8;  pD3D := Direct3DCreate9(D3D_SDK_VERSION);  pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetDesktopWindow,    D3DCREATE_SOFTWARE_VERTEXPROCESSING, @D3DPP, g_pD3DDevice);  g_pD3DDevice.CreateOffscreenPlainSurface(Screen.Width, Screen.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, pSurface, nil);  g_pD3DDevice.GetFrontBufferData(0, pSurface);  // use D3D to save surface. Notes: D3DX%ab.dll is required!//  D3DXSaveSurfaceToFile('Desktop.bmp', D3DXIFF_BMP, pSurface, nil,  nil);  // use Bitmap to save surface  ARect := Screen.DesktopRect;  pSurface.LockRect(LockedRect, @ARect, D3DLOCK_NO_DIRTY_UPDATE or D3DLOCK_NOSYSLOCK or D3DLOCK_READONLY);  BMP := TBitmap.Create;  BMP.Width := Screen.Width;  BMP.Height := Screen.Height;  case BitsPerPixel of    8:  BMP.PixelFormat := pf8bit;    16: BMP.PixelFormat := pf16bit;    24: BMP.PixelFormat := pf24bit;    32: BMP.PixelFormat := pf32bit;  end;  p := Cardinal(LockedRect.pBits);  for i := 0 to Screen.Height - 1 do    begin      CopyMemory(BMP.ScanLine[i], Ptr(p), Screen.Width * BitsPerPixel div 8);      p := p + LockedRect.Pitch;    end;  BMP.SaveToFile(FileName);  BMP.Free;  pSurface.UnlockRect;end;procedure CaptureScreen(const FileName: string;Const FileType: TD3DXImageFileFormat);var  pD3D: IDirect3D9;  pSurface: IDirect3DSurface9;  g_pD3DDevice: IDirect3DDevice9;  D3DPP: TD3DPresentParameters;begin  FillChar(d3dpp, SizeOf(d3dpp), 0);  D3DPP.Windowed := True;  D3DPP.Flags := D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;  D3DPP.SwapEffect := D3DSWAPEFFECT_DISCARD;  D3DPP.BackBufferWidth := Screen.Width;  D3DPP.BackBufferHeight := Screen.Height;  D3DPP.BackBufferFormat := D3DFMT_X8R8G8B8;  pD3D := Direct3DCreate9(D3D_SDK_VERSION);  pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetDesktopWindow,    D3DCREATE_SOFTWARE_VERTEXPROCESSING, @D3DPP, g_pD3DDevice);  g_pD3DDevice.CreateOffscreenPlainSurface(Screen.Width, Screen.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, pSurface, nil);  g_pD3DDevice.GetFrontBufferData(0, pSurface);  D3DX9.D3DXSaveSurfaceToFile(PChar(FileName),FileType,pSurface,nil,nil);  pSurface := nil;  g_pD3DDevice := nil;  pD3D :=  nil;end; 传递两个参数,第一个参数指定为文件名,第二个参数指定为文件类型支持7种类型_D3DXIMAGE_FILEFORMAT = (    D3DXIFF_BMP        {
= 0}, D3DXIFF_JPG {
= 1}, D3DXIFF_TGA {
= 2}, D3DXIFF_PNG {
= 3}, D3DXIFF_DDS {
= 4}, D3DXIFF_PPM {
= 5}, D3DXIFF_DIB {
= 6} );再给一个使用dX8实现的,上面给的是用Dx9实现的函数procedure CaptureScreen(const FileName: string;Const FileType: TD3DXImageFileFormat);var pD3D: IDirect3D8; pSurface: IDirect3DSurface8; g_pD3DDevice: IDirect3DDevice8; D3DPP: TD3DPresentParameters;begin FillChar(d3dpp, SizeOf(d3dpp), 0); D3DPP.Windowed := True; D3DPP.Flags := D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; D3DPP.SwapEffect := D3DSWAPEFFECT_DISCARD; D3DPP.BackBufferWidth := Screen.Width; D3DPP.BackBufferHeight := Screen.Height; D3DPP.BackBufferFormat := D3DFMT_X8R8G8B8; pD3D := Direct3DCreate8(D3D_SDK_VERSION); pD3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetDesktopWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, D3DPP, g_pD3DDevice); g_pD3DDevice.CreateImageSurface(Screen.Width, Screen.Height, D3DFMT_A8R8G8B8, pSurface); g_pD3DDevice.GetFrontBuffer(pSurface); D3DX8.D3DXSaveSurfaceToFile(PChar(FileName),FileType,pSurface,nil,nil); pSurface := nil; g_pD3DDevice := nil; pD3D := nil;end;再给一个直接使用系统GDI实现的抓屏procedure CaptureScreen(const FileName: string);overload;var nScreenWidth,nScreenHeight: integer; ScreenDc,hCaptureDC: HDC; bmp: TBitmap;begin nScreenWidth := GetSystemMetrics(SM_CXSCREEN); nScreenHeight := GetSystemMetrics(SM_CYSCREEN); ScreenDc := GetDC(GetDesktopWindow); hCaptureDC := CreateCompatibleDC(ScreenDc); bmp := TBitmap.Create; bmp.Handle :=CreateCompatibleBitmap(ScreenDc,nScreenWidth, nScreenHeight); SelectObject(hCaptureDC,bmp.Handle); BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight,ScreenDc,0,0,SRCCOPY); bmp.SaveToFile(fileName); ReleaseDC(GetDesktopWindow,ScreenDc); DeleteDC(hCaptureDC); bmp.Free;end;通过上面这一步,我们可以很容易联想到用来抓取任何一个控件的表面图象,函数如下:procedure CaptureControl(Control: TWinControl;const FileName: string);overload;var ControlWidth,ControlHeight: integer; ControlDc,hCaptureDC: HDC; bmp: TBitmap;begin ControlWidth := Control.ClientWidth; ControlHeight := Control.ClientHeight; ControlDc := GetDC(Control.Handle); hCaptureDC := CreateCompatibleDC(ControlDc); bmp := TBitmap.Create; bmp.Handle :=CreateCompatibleBitmap(ControlDc,ControlWidth,ControlHeight); SelectObject(hCaptureDC,bmp.Handle); BitBlt(hCaptureDC,0,0,ControlWidth,ControlHeight,ControlDc,0,0,SRCCOPY); bmp.SaveToFile(fileName); ReleaseDC(GetDesktopWindow,ControlDc); DeleteDC(hCaptureDC); bmp.Free;end;

 

转载于:https://www.cnblogs.com/m0488/archive/2013/05/18/3086138.html

你可能感兴趣的文章
async/await让我们更好的写异步代码
查看>>
react输入框输入中文bug
查看>>
Linux命令整理
查看>>
SQL2000的卸载步骤
查看>>
Sql不区分大小写查询
查看>>
二分法查找
查看>>
180. Consecutive Numbers (Medium)
查看>>
Android开发中多进程共享数据
查看>>
神经网络 线性单元
查看>>
12生成器,send,推导式
查看>>
关于使用READ TABLE语句
查看>>
敏感词汇过滤DFA算法
查看>>
multipart/form-data post 方法提交表单,后台获取不到数据
查看>>
LNMP环境搭建(CentOS7+Nginx1.10.1+MySQL5.6.31+PHP5.6.22)
查看>>
Moon.ORM4.3及代码生成器企业版2.0评估版发布.欢迎下载(勿用IE6)
查看>>
Python实现KNN算法及手写程序识别
查看>>
笔记14 | 图片倒影+渐变效果
查看>>
js 时间戳
查看>>
【转】JMeter工作基本原理
查看>>
设计模式眨一眨
查看>>