|
Registriert seit: 17. Nov 2005 Ort: Hamburg 1.087 Beiträge Delphi XE2 Professional |
#11
TPicture.LoadFromFile wäre auch noch da
![]() TPicture.LoadFromFile arbeitet zwar recht flott, aber Canvas.StretchDraw(ClientRect,Picture.Graphic) ist dafür umso langsamer. Ich hab mal alle Varianten durchprobiert. Die beste Alternative scheint zu sein: 1) GPImage oder GPBitmap laden 2) In TBitmap kopieren 3) TBitmap mit StretchBlt ausgeben. Letztendlich reduziert sich alles auf die Ausgangsfrage: Weiß jemand, wie man eine GPBitmap schnell ausgibt? Und so sind die Zeiten, die ich ermittelt habe. Bei mehreren Testen hintereinander weichen die Zeiten zwar ab, aber die Relation der Zeiten für die verschiedenen Abläufe ändert sich nicht wesentlich. Parameter : .jpg Datei, 4000x3000 Pixel, Größe des Canvas : 1920 x 1000 Pixel LoadGPImage 0.731 ms LoadGPBitmap 0.558 ms LoadWicImage 141.564 ms LoadPicture 2.989 ms LoadBmpViaJPEG 966.952 ms LoadBmpViaGPImage 243.285 ms LoadBmpViaGPBitmap 243.314 ms LoadBmpViaWicImage 387.731 ms LoadBmpViaPicture 984.076 ms DrawBitmap 2.729 ms DrawGPImage 174.647 ms DrawGPBitmap 174.511 ms DrawWicImage 262.219 ms DrawPicture 990.640 MS Zur Vollständigkeit die komplette (aktualisierte) Test Prozedur. Vielleicht macht Ihre Euch die Mühe und schaut die einmal kritisch durch, denn seine eigenend kleinen Flüchtigkeitsfehler übersieht man ja oft.
Delphi-Quellcode:
PROCEDURE TMain.Test;
//------------------------------------------------------------------------------ FUNCTION TimeStamp:Int64; asm rdtsc {$IFDEF CPUX64} shl rdx,32 or rax,rdx {$ENDIF} end; //------------------------------------------------------------------------------ FUNCTION FixCPU(var PaMask:NativeUInt):Boolean; var SaMask,TaMask:NativeUInt; begin GetProcessAffinityMask(GetCurrentProcess,PaMask,SaMask); if PaMask<>0 then begin TaMask:=1; while (TaMask<>0) and ((TaMask and PaMask)=0) do TaMask:=TaMask shl 1; if TaMask<>0 then SetThreadAffinityMask(GetCurrentThread,TaMask); Result:=TaMask<>0; end else begin Result:=False; end; end; //------------------------------------------------------------------------------ FUNCTION GetTimeStampFrequency:Int64; var OldPriority:Word; Q0,Q1,Qf,Ts0,Ts1:Int64; Seconds:Extended; PaMask:NativeUInt; Fixed:Boolean; begin // Thread nur auf einer CPU ausführen Fixed:=FixCPU(PaMask); // Priorität des Threads hochsetzen OldPriority:=GetThreadPriority(GetCurrentThread); SetThreadPriority(GetCurrentThread,THREAD_PRIORITY_TIME_CRITICAL); // QPC- und TimeStamp-Ticks für 10 ms holen QueryPerformanceCounter(Q0); Ts0:=TimeStamp; Sleep(10); Ts1:=TimeStamp; QueryPerformanceCounter(Q1); // Anhand QPF die TimeStamp-Frequenz ermitteln QueryPerformanceFrequency(Qf); Seconds:=(Q1-Q0)/Qf; Result:=Trunc((Ts1-Ts0)/Seconds+0.5); // Ticks/s // Priorität des Threads auf alten Wert stellen und Thread für alle // CPUs freigeben SetThreadPriority(GetCurrentThread,OldPriority); if Fixed and (PaMask<>0) then SetThreadAffinityMask(GetCurrentThread,PaMask); end; //------------------------------------------------------------------------------ FUNCTION LoadGPImage(const Dsn:String):Int64; var I:Integer; Image:TGPImage; begin Result:=TimeStamp; Image:=TGPImage.Create(Dsn); Result:=TimeStamp-Result; Image.Free; end; //------------------------------------------------------------------------------ FUNCTION LoadGPBitmap(const Dsn:String):Int64; var Image:TGPBitmap; begin Result:=TimeStamp; Image:=TGPBitmap.Create(Dsn); Result:=TimeStamp-Result; Image.Free; end; //------------------------------------------------------------------------------ FUNCTION LoadWicImage(const Dsn:String):Int64; var WicImage:TWicImage; begin WicImage:=TWicImage.Create; Result:=TimeStamp; WicImage.LoadFromFile(Dsn); Result:=TimeStamp-Result; WicImage.Free; end; //------------------------------------------------------------------------------ FUNCTION LoadBmpViaJPEG(const Dsn:String):Int64; var Jpg:TJpegImage; Bmp:TBitmap; begin Bmp:=TBitmap.Create; Result:=TimeStamp; Jpg:=TJPEGImage.Create; Jpg.LoadFromFile(Dsn); Bmp.Assign(Jpg); Jpg.Free; Result:=TimeStamp-Result; Bmp.Free; end; //------------------------------------------------------------------------------ FUNCTION LoadBmpViaGPImage(const Dsn:String):Int64; var W,H:Integer; Image:TGPImage; Graphics:TGPGraphics; Bmp:TBitmap; begin Bmp:=TBitmap.Create; Result:=TimeStamp; Image:=TGPImage.Create(Dsn); W:=Image.GetWidth; H:=Image.GetHeight; Bmp.SetSize(W,H); Graphics:=TGPGraphics.Create(Bmp.Canvas.Handle); Graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic); Graphics.DrawImage(Image,MakeRect(0,0,W,H)); Graphics.Free; Image.Free; Result:=TimeStamp-Result; Bmp.Free; end; //------------------------------------------------------------------------------ FUNCTION LoadBmpViaGPBitmap(const Dsn:String):Int64; var W,H:Integer; Image:TGPBitmap; Graphics:TGPGraphics; Bmp:TBitmap; begin Bmp:=TBitmap.Create; Result:=TimeStamp; Image:=TGPBitmap.Create(Dsn); W:=Image.GetWidth; H:=Image.GetHeight; Bmp.SetSize(W,H); Graphics:=TGPGraphics.Create(Bmp.Canvas.Handle); Graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic); Graphics.DrawImage(Image,MakeRect(0,0,W,H)); Graphics.Free; Image.Free; Result:=TimeStamp-Result; Bmp.Free; end; //------------------------------------------------------------------------------ FUNCTION LoadBmpViaWicImage(const Dsn:String):Int64; var WicImage:TWicImage; Bmp:TBitmap; begin Bmp:=TBitmap.Create; Result:=TimeStamp; WicImage:=TWicImage.Create; WicImage.LoadFromFile(Dsn); Bmp.Assign(WicImage); WicImage.Free; Result:=TimeStamp-Result; Bmp.Free; end; //------------------------------------------------------------------------------ FUNCTION LoadPicture(const Dsn:String):Int64; var Picture:TPicture; begin Picture:=TPicture.Create; Result:=TimeStamp; Picture.LoadFromFile(Dsn); Result:=TimeStamp-Result; Picture.Free; end; //------------------------------------------------------------------------------ FUNCTION LoadBmpViaPicture(const Dsn:String):Int64; var Picture:TPicture; Bmp:TBitmap; begin Bmp:=TBitmap.Create; Result:=TimeStamp; Picture:=TPicture.Create; Picture.LoadFromFile(Dsn); Bmp.Assign(Picture.Graphic); Picture.Free; Result:=TimeStamp-Result; Bmp.Free; end; //------------------------------------------------------------------------------ FUNCTION DrawBitmap(const Dsn:String):Int64; var W,H:Integer; Image:TGPImage; Graphics:TGPGraphics; Bmp:TBitmap; begin Bmp:=TBitmap.Create; Image:=TGPImage.Create(Dsn); W:=Image.GetWidth; H:=Image.GetHeight; Bmp.SetSize(W,H); Graphics:=TGPGraphics.Create(Bmp.Canvas.Handle); Graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic); Graphics.DrawImage(Image,MakeRect(0,0,W,H)); Graphics.Free; Image.Free; Result:=TimeStamp; SetStretchBltMode(Canvas.Handle,COLORONCOLOR); SetBrushOrgEx(Canvas.Handle,0,0,nil); StretchBlt(Canvas.Handle,0,0,ClientWidth,ClientHeight, Bmp.Canvas.Handle,0,0,Bmp.Width,Bmp.Height,SrcCopy); Result:=TimeStamp-Result; Bmp.Free end; //------------------------------------------------------------------------------ FUNCTION DrawGPImage(const Dsn:String):Int64; var I:Integer; Image:TGPImage; Graphics:TGPGraphics; begin Image:=TGPImage.Create(Dsn,True); Result:=TimeStamp; Graphics:=TGPGraphics.Create(Canvas.Handle); Graphics.SetInterpolationMode(InterpolationModeNearestNeighbor); Graphics.DrawImage(Image,MakeRect(0,0,ClientWidth,ClientHeight)); Graphics.Free; Result:=TimeStamp-Result; Image.Free; end; //------------------------------------------------------------------------------ FUNCTION DrawGPBitmap(const Dsn:String):Int64; var I:Integer; Image:TGPBitmap; Graphics:TGPGraphics; begin Image:=TGPBitmap.Create(Dsn,True); Result:=TimeStamp; Graphics:=TGPGraphics.Create(Canvas.Handle); Graphics.SetInterpolationMode(InterpolationModeNearestNeighbor); Graphics.DrawImage(Image,MakeRect(0,0,ClientWidth,ClientHeight)); Graphics.Free; Result:=TimeStamp-Result; Image.Free; // InterpolationModeInvalid 270 // InterpolationModeDefault 270 // InterpolationModeLowQuality 270 // InterpolationModeHighQuality 325 // InterpolationModeBilinear 270 // InterpolationModeBicubic 620 // InterpolationModeNearestNeighbor 180 // InterpolationModeHighQualityBilinear 370 // InterpolationModeHighQualityBicubic 320 end; //------------------------------------------------------------------------------ FUNCTION DrawWicImage(const Dsn:String):Int64; var WicImage:TWicImage; begin WicImage:=TWicImage.Create; WicImage.LoadFromFile(Dsn); Result:=TimeStamp; Canvas.StretchDraw(ClientRect,WicImage); Result:=TimeStamp-Result; WicImage.Free; end; //------------------------------------------------------------------------------ FUNCTION DrawPicture(const Dsn:String):Int64; var Picture:TPicture; begin Picture:=TPicture.Create; Picture.LoadFromFile(Dsn); Result:=TimeStamp; Canvas.StretchDraw(ClientRect,Picture.Graphic); Result:=TimeStamp-Result; Picture.Free; end; //------------------------------------------------------------------------------ var Results:String; PROCEDURE Add(TSC,TSF:Int64; const FuncName:String); var S:String; begin if Results<>'' then Results:=Results+#13#10; if TSF=0 then begin S:=IntToStr(TSC)+' CPU-Ticks' end else begin Str(TSC/TSF*1000:0:3,S); S:=S+' ms'; end; Results:=Results+FuncName+' '+S end; //------------------------------------------------------------------------------ // https://commons.wikimedia.org/w/index.php?curid=6558322 const Dsn='E:\Daten\DownLoads\PfauVonVorne.jpg'; var TSF:Int64; PaMask:NativeUInt; CPUFixed:Boolean; begin TSF:=GetTimeStampFrequency; CPUFixed:=FixCPU(PaMask); Add(LoadGPImage(Dsn),TSF,'LoadGPImage'); Add(LoadGPBitmap(Dsn),TSF,'LoadGPBitmap'); Add(LoadWicImage(Dsn),TSF,'LoadWicImage'); Add(LoadPicture(Dsn),TSF,'LoadPicture'); Results:=Results+#13#10; Add(LoadBmpViaJPEG(Dsn),TSF,'LoadBmpViaJPEG'); Add(LoadBmpViaGPImage(Dsn),TSF,'LoadBmpViaGPImage'); Add(LoadBmpViaGPBitmap(Dsn),TSF,'LoadBmpViaGPBitmap'); Add(LoadBmpViaWicImage(Dsn),TSF,'LoadBmpViaWicImage'); Add(LoadBmpViaPicture(Dsn),TSF,'LoadBmpViaPicture'); Results:=Results+#13#10; Add(DrawBitmap(Dsn),TSF,'DrawBitmap'); Add(DrawGPImage(Dsn),TSF,'DrawGPImage'); Add(DrawGPBitmap(Dsn),TSF,'DrawGPBitmap'); Add(DrawWicImage(Dsn),TSF,'DrawWicImage'); Add(DrawPicture(Dsn),TSF,'DrawPicture'); if CPUFixed and (PaMask<>0) then SetThreadAffinityMask(GetCurrentThread,PaMask); Clipboard.AsText:=Results; ShowMessage(Results); end;
Gruß, Klaus
Die Titanic wurde von Profis gebaut, die Arche Noah von einem Amateur. ... Und dieser Beitrag vom Amateurprofi.... |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs 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
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |