![]() |
Screenshot von DirectX
Mit der folgenden Procedure kann ich das aktuell angezeigte Bild als Bitmap speichern:
Delphi-Quellcode:
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
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;
Delphi-Quellcode:
erhalte ich dann mit
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.dll' name 'GdipCreateBitmapFromGdiDib';
Delphi-Quellcode:
einen Pointer auf ein Bitmap. Ich weiß nun allerdings nicht, wie ich dann an das Bitmap herankomme.
GdipCreateBitmapFromGdiDib(@bmpinfo, pDIBImage, pBitmap);
|
Re: Screenshot von DirectX
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 ? |
Re: Screenshot von DirectX
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. |
Re: Screenshot von DirectX
Mit der Funktion GdipCreateHBITMAPFromBitmap bekommt man das Handle zum Pointer des Bitmaps.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:48 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz