• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Delphi中使用DirectX截屏函数

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
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;

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Delphi 调用SQL Server 2008存储过程发布时间:2022-07-18
下一篇:
利用Delphi编写IE扩展发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap