基于IWICImage的截图代码

截图方式和以前一样, 用GetDC, 保存为JPG的方式改用IWICImage接口, 在我机器上 1920*1080 大概花费70毫秒左右, 比用TJPEGImage快了一倍多(TJPEGImage需要160毫秒左右)

直接上代码

uses
  Winapi.ActiveX, Winapi.Wincodec;

{$R *.dfm}

{将TWICImage的 CreateWicBitmap和SaveToStream摘出来}
procedure _SaveToStream(ABMP: TBitmap; Stream: TMemoryStream);
var
  nPixelFormat: TGUID;
  nBitmapInfo: TBitmapInfo;
  nBuffer: array of byte;
  nHBMP: HBITMAP;

  nEncoder: IWICBitmapEncoder;
  nFrame: IWICBitmapFrameEncode;
  nProps: IPropertyBag2;
  nLStreamAdapter: IStream;
  nLStream: IWICStream;
  nPalette: IWICPalette;
  nWicBitmap: IWICBitmap;

  nWidth, nHeight: Integer;
  nWICFactory: IWICImagingFactory;
begin
  CoCreateInstance(CLSID_WICImagingFactory, nil, CLSCTX_INPROC_SERVER or
    CLSCTX_LOCAL_SERVER, IUnknown, nWICFactory);

  nPixelFormat := GUID_WICPixelFormat24bppBGR;
  nWidth := ABMP.Width;
  nHeight := ABMP.Height;

  ABMP.PixelFormat := pf24bit;

  SetLength(nBuffer, nWidth * 3 * nHeight);

  FillChar(nBitmapInfo, sizeof(nBitmapInfo), 0);
  nBitmapInfo.bmiHeader.biSize := SizeOf(nBitmapInfo);
  nBitmapInfo.bmiHeader.biWidth := nWidth;
  nBitmapInfo.bmiHeader.biHeight := -nHeight;
  nBitmapInfo.bmiHeader.biPlanes := 1;
  nBitmapInfo.bmiHeader.biBitCount := 24;
  // Forces evaluation of Bitmap.Handle before Bitmap.Canvas.Handle
  nHBMP := ABMP.Handle;
  GetDIBits(ABMP.Canvas.Handle,  nHBMP, 0, nHeight, @nBuffer[0],
    nBitmapInfo, DIB_RGB_COLORS);
  nWicBitmap := nil;
  nWICFactory.CreateBitmapFromMemory(nWidth, nHeight, nPixelFormat,
    nWidth * 3, Length(nBuffer), @nBuffer[0], nWicBitmap);

  Stream.Clear;
  nLStreamAdapter := TStreamAdapter.Create(Stream);

  nWICFactory.CreateStream(nLStream);
  nLStream.InitializeFromIStream(nLStreamAdapter);
  nWICFactory.CreateEncoder(GUID_ContainerFormatJpeg, guid_null, nEncoder);

  nEncoder.Initialize(nLStream, WICBitmapEncoderNoCache);
  nEncoder.CreateNewFrame(nFrame, nProps);

  nFrame.Initialize(nProps);
  nWicBitmap.GetPixelFormat(nPixelFormat);
  nFrame.SetPixelFormat(nPixelFormat);

  nFrame.SetSize(nWidth, nHeight);

  nWICFactory.CreatePalette(nPalette);
  nWicBitmap.CopyPalette(nPalette);
  nFrame.SetPalette(nPalette);
  nFrame.WriteSource(nWicBitmap, nil);
  nFrame.Commit;
  nEncoder.Commit;

  Stream.Position := 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  nHDC: HDC;
  nBmp: TBitmap;
  nMS: TMemoryStream;
  nWic: TWICImage;
begin
  nMS := TMemoryStream.Create;
  nBmp := TBitmap.Create;
  try
    nHDC := GetDC(0);
    nMS.Clear;
    nBmp.PixelFormat := pf24bit;
    nBmp.Width := Screen.Width;
    nBmp.Height := Screen.Height;
    {这里大概花费60毫秒, 应该可以再快}
    BitBlt(nBmp.Canvas.Handle, 0, 0, nBmp.Width, nBmp.Height, nHDC, 0, 0, cmSrcCopy);
    ReleaseDC(0, nHDC);
    _SaveToStream(nBmp, nMS);

    {查看截图内容, 10毫秒左右, 不计入截图时间}
    nWic := TWICImage.Create;
    nWic.ImageFormat := wifJpeg;
    nWic.LoadFromStream(nMS);
    Image1.Picture.Assign(nWic);
    nWic.Free;
  finally
    nBmp.Free;
    nMS.Free;
  end;
end;

 

posted on 2017-07-17 16:54 堕落恶魔 阅读(...) 评论(...) 编辑 收藏

统计