• Delphi中使用DirectX截屏函数


    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;
  • 相关阅读:
    FEniCS 1.1.0 发布,计算算术模型
    Piwik 1.10 发布,增加社交网站统计
    淘宝褚霸谈做技术的心态
    CyanogenMod 10.1 M1 发布
    Druid 发布 0.2.11 版本,数据库连接池
    GNU Gatekeeper 3.2 发布
    Phalcon 0.9.0 BETA版本发布,新增大量功能
    EUGene 2.6.1 发布,UML 模型操作工具
    CVSps 3.10 发布,CVS 资料库更改收集
    Opera 移动版将采用 WebKit 引擎
  • 原文地址:https://www.cnblogs.com/karkash/p/3086138.html
Copyright © 2020-2023  润新知