• 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;
  • 相关阅读:
    mobx源码解读1
    表单元素之图形系
    koa2+koa-views示例
    avalon2的后端渲染实践
    向一个数组中插入元素
    一步步编写avalon组件02:分页组件
    avalon2学习教程15指令总结
    avalon2学习教程14动画使用
    WPF动态加载Menu菜单
    WPF自定义控件与样式 ---- 系列文章
  • 原文地址:https://www.cnblogs.com/karkash/p/3086138.html
Copyright © 2020-2023  润新知