Thema: Delphi Screenshot von DirectX

Einzelnen Beitrag anzeigen

Benutzerbild von Garfield
Garfield

Registriert seit: 9. Jul 2004
Ort: Aken (Anhalt-Bitterfeld)
1.335 Beiträge
 
Delphi XE5 Professional
 
#1

Screenshot von DirectX

  Alt 23. Okt 2009, 11:55
Mit der folgenden Procedure kann ich das aktuell angezeigte Bild als Bitmap speichern:

Delphi-Quellcode:
procedure TDSPlayer.SetSaveImage(Value: String);
var
  BufferSize : Integer;
  DIBImage : Array of Byte;
  pDIBImage : Pointer;
  lWidth : Integer;
  lHeight : Integer;
  hRes : HRESULT;
  bmphdr : BITMAPFILEHEADER;
  bmpinfo : BITMAPINFOHEADER;
  nWritten : DWORD;
  fh : THandle;
begin
  fh := 0;
  pDIBImage := nil;
  {
  *  Wenn ein Videostream vorhanden ist, das Bild holen.
  }

  if isVideo
  then try
    {
    *  HRESULT GetCurrentImage(
    *    [in, out] long *pBufferSize,
    *    [out]    long *pDIBImage
    *  );
    *
    *  Beim ersten Aufruf muss die Buffersize 0 und der Pointer nil sein, dann
    *  erhält man die erforderliche Buffersize.
    }

    pDIBImage := nil;
    BufferSize := 0;
    hRes := FBasicVideo.getCurrentImage(BufferSize, pDIBImage^);
    if (hRes <> S_OK)
    then raise Exception.Create(Format('%s'#10#13'Error Code: %s', [GetErrorString(hRes), IntToHex(hRes, 8)]));
    {
    *  Es wird der Speicher bereitgestellt und der Aufruf erfolgt mit der rich-
    *  tigen Speichergröße sowie dem Zeiger auf den bereitgestellten Speicher.
    }

    setLength(DIBImage, BufferSize);
    pDIBImage := @DIBImage[0];
    FBasicVideo.GetCurrentImage(BufferSize, pDIBImage^);
    {
    *  Bitmapgröße
    }

    FBasicVideo.get_VideoWidth(lWidth);
    FBasicVideo.get_VideoHeight(lHeight);
    {
    *  Speicher für Bitmapdateiheader und Bitmapinfoheader bereitstellen
    }

    FillChar(bmphdr, SizeOf(bmphdr), 0);
    FillChar(bmpinfo, SizeOf(bmpinfo), 0);
    {
    *  Den Bitmapdateiheader erstellen
    }

    bmphdr.bfType := $4D42;
    bmphdr.bfSize := sizeof(bmphdr) + sizeof(bmpinfo) + BufferSize;
    bmphdr.bfOffBits := sizeof(bmphdr) + sizeof(bmpinfo);
    {
    *  Den Bitmapinfoheader erstellen
    }

    bmpinfo.biSize := sizeof(bmpinfo);
    bmpinfo.biWidth := lwidth;
    bmpinfo.biHeight := lheight;
    bmpinfo.biPlanes := 1;
    bmpinfo.biBitCount := 32;
    {
    *  Dateierweiterung kontrollieren
    }

    if ExtractFileExt(LowerCase(Value)) <> '.bmp'
    then Value := ChangeFileExt(Value, '.bmp');
    {
    *  Die Datei schreiben
    }

    fh := CreateFile(PChar(Value), GENERIC_WRITE, 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    if fh <> INVALID_HANDLE_VALUE
    then begin
      WriteFile(fh, bmphdr, sizeof(bmphdr), nWritten, nil);
      WriteFile(fh, bmpinfo, sizeof(bmpinfo), nWritten, nil);
      WriteFile(fh, pDIBImage^, BufferSize, nWritten, nil);
    end
    else raise Exception.Create(GetLastError);
  finally
    CloseHandle(fh);
  end;
end;
Anstelle das Bild sofort zu speichern möchte ich lieber ein Bitmap zurück bekommen. Wenn ich einen TStream und anstelle WriteFile aStream.Write verwende, bekomme ich bei aBitmap.LoadFromStream nur einen Fehler. Als Alternative habe ich die Verwendung der GDI gefunden. Nach der Deklaration von

Delphi-Quellcode:
type
  {$EXTERNALSYM Status}
  Status = (
    Ok,
    GenericError,
    InvalidParameter,
    OutOfMemory,
    ObjectBusy,
    InsufficientBuffer,
    NotImplemented,
    Win32Error,
    WrongState,
    Aborted,
    FileNotFound,
    ValueOverflow,
    AccessDenied,
    UnknownImageFormat,
    FontFamilyNotFound,
    FontStyleNotFound,
    NotTrueTypeFont,
    UnsupportedGdiplusVersion,
    GdiplusNotInitialized,
    PropertyNotFound,
    PropertyNotSupported
  );
  TStatus = Status;
  GpStatus = TStatus;
  GpBitmap = Pointer;
  {$EXTERNALSYM GdipCreateBitmapFromGdiDib}
  function GdipCreateBitmapFromGdiDib(gdiBitmapInfo: PBitmapInfo; gdiBitmapData: Pointer; out bitmap: GPBITMAP): GPSTATUS; stdcall;
           external 'gdiplus.dllname 'GdipCreateBitmapFromGdiDib';
erhalte ich dann mit GdipCreateBitmapFromGdiDib(@bmpinfo, pDIBImage, pBitmap); einen Pointer auf ein Bitmap. Ich weiß nun allerdings nicht, wie ich dann an das Bitmap herankomme.
Gruss Garfield
Ubuntu 22.04: Laz2.2.2/FPC3.2.2 - VirtBox6.1+W10: D7PE, DXE5Prof
  Mit Zitat antworten Zitat