AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Screenshot von DirectX
Thema durchsuchen
Ansicht
Themen-Optionen

Screenshot von DirectX

Ein Thema von Garfield · begonnen am 23. Okt 2009 · letzter Beitrag vom 24. Okt 2009
Antwort Antwort
Benutzerbild von Garfield
Garfield

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

Screenshot von DirectX

  Alt 23. Okt 2009, 10: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
Benutzerbild von erich.wanker
erich.wanker

Registriert seit: 31. Jan 2008
Ort: im schönen Salzburger Land
454 Beiträge
 
Delphi XE4 Professional
 
#2

Re: Screenshot von DirectX

  Alt 23. Okt 2009, 15:04
Hallo Garfield,

ich hab grad ein kleines Programm (greift auf DirectX zu) funktionstüchtig, welches einen Videostream von einer Webcam abgreift und in einem Image (via Timer [intervall 100]) darstellt..

Das Bild kann dann via drag&Drop oder via jpegImg.SaveToFile abgespeichert werden..

würde dir das helfen ?
Erich Wanker - for life:=1971 to lebensende do begin ..
  Mit Zitat antworten Zitat
Benutzerbild von Garfield
Garfield

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

Re: Screenshot von DirectX

  Alt 23. Okt 2009, 17:27
Hallo erich,

Dein IVideoWindow ist ein TImage und dieses wird dann als JPEG gespeichert?

Mein IVideoWindow ist ein TPanel. Hatte auch überlegt, ob man den Canvas kopieren kann. Eventuell stimmt dann der AspectRatio ohne weitere Bearbeitung, wobei dann wohl auch die verwendete Skalierung berücksichtigt wird. Deshalb wollte ich eine Kopie des Quellbildes machen. Eventuell mit Berücksichtigung des AspectRatio. Alternativ hatte ich es mit ISampleGrabber versucht. Das habe ich dann wieder gelöscht, weil kein Ergebnis herausgekommen war.
Gruss Garfield
Ubuntu 22.04: Laz2.2.2/FPC3.2.2 - VirtBox6.1+W10: D7PE, DXE5Prof
  Mit Zitat antworten Zitat
Benutzerbild von Garfield
Garfield

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

Re: Screenshot von DirectX

  Alt 24. Okt 2009, 11:24
Mit der Funktion GdipCreateHBITMAPFromBitmap bekommt man das Handle zum Pointer des Bitmaps.
Gruss Garfield
Ubuntu 22.04: Laz2.2.2/FPC3.2.2 - VirtBox6.1+W10: D7PE, DXE5Prof
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz