AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Bitmap zeichen (gehts noch schneller?)
Thema durchsuchen
Ansicht
Themen-Optionen

Bitmap zeichen (gehts noch schneller?)

Ein Thema von Amateurprofi · begonnen am 28. Feb 2016 · letzter Beitrag vom 1. Mär 2016
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
737 Beiträge
 
#11

AW: Bitmap zeichen (gehts noch schneller?)

  Alt 29. Feb 2016, 14:50
TPicture.LoadFromFile wäre auch noch da
Da man Trunc nicht auf einen Integer anwenden kann, muss dieser zuerst in eine Float kopiert werden
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.077 Beiträge
 
Delphi XE2 Professional
 
#12

AW: Bitmap zeichen (gehts noch schneller?)

  Alt 29. Feb 2016, 23:25
Da ich das Bild nur ausgeben kann, wenn ich es vorher lade, drängt sich das laden in eine TGPBitmap förmlich auf.
Wenn es dir einzig und allein darum geht, verschiedene Grafik-Formate zu laden und du sonst nichts mit der GDI+-Biblothek machst, kannst du auch Vcl.Graphics.TWicImage nehmen.

Siehe hier:
http://www.tek-tips.com/faqs.cfm?fid=7568
Hallo TiGü:
kannte ich auch noch nicht.
Ist aber keine Alternative, weil recht bummelig.
Im nächsten Beitrag werde ich das mal alles zusammenfassen.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.077 Beiträge
 
Delphi XE2 Professional
 
#13

AW: Bitmap zeichen (gehts noch schneller?)

  Alt 29. Feb 2016, 23:57
TPicture.LoadFromFile wäre auch noch da
Hallo Memnarch,

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....
  Mit Zitat antworten Zitat
Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
737 Beiträge
 
#14

AW: Bitmap zeichen (gehts noch schneller?)

  Alt 1. Mär 2016, 00:00
Eine TBitmap mit Pixelformat32 (IIRC) welches du direkt auf den Canvas zeichnest (warum gehst du zum zeichnen der TBitmap über TGPGraphic?) sollte das schnellste sein
Da man Trunc nicht auf einen Integer anwenden kann, muss dieser zuerst in eine Float kopiert werden
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.077 Beiträge
 
Delphi XE2 Professional
 
#15

AW: Bitmap zeichen (gehts noch schneller?)

  Alt 1. Mär 2016, 19:20
Eine TBitmap mit Pixelformat32 (IIRC) welches du direkt auf den Canvas zeichnest (warum gehst du zum zeichnen der TBitmap über TGPGraphic?) sollte das schnellste sein
Hallo Memnarch,
Zu "warum gehst du zum zeichnen der TBitmap über TGPGraphic?"
Mache ich nicht! Entweder habe ich mich undeutlich ausgedrückt oder Du hast falsch gelesen.
Ich schrieb:
1) GPImage oder GPBitmap laden
2) In TBitmap kopieren
3) TBitmap mit StretchBlt ausgeben.
Ich lade also die Datei in ein TGPImage oder TGBBitmap, kopiere diese in eine TBitmap und zeichne die TBitmap mit StretchBlt.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 15:40 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