Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi schnellerer Zugriff auf Tbitmap (https://www.delphipraxis.net/34862-schnellerer-zugriff-auf-tbitmap.html)

cumi 29. Nov 2004 14:14


schnellerer Zugriff auf Tbitmap
 
Also bis jetzt greif ich so auf meine TBitMap-Variabel zu:
Delphi-Quellcode:
imgColor.Canvas.Pixels[s,z]:=CalcColor(aDivVal[s,z]);
nun hab ich rausgefunden, dass das Ansprechen von der imgColor Variabel sehrsehr langsam funktioniert. Ich brauche sicher 100mal so viel zeit für diese Zuweisung als für das berechnen von CalcColor(...).
Jetzt gibt es da keine schnellere Variante um auf eine TBitMap-Variabel zuzugreifen? Oder wass muss den da so extrem gerechnet werden? Wenn ich eine 2D Array of TColor habe funktioniert das ganze vielviel schneller....

Danke schon im Voraus...

Sanchez 29. Nov 2004 14:18

Re: schnellerer Zugriff auf Tbitmap
 
Hallo,
Langsam ist nicht der Zugriff auf das TBitmap sondern der auf die Pixels.
Such mal hier nach ScanLine oder schau dir das Tutorial (http://www.delphi-source.de/tutorials/bitmap/ ) mal an.

grüße, daniel

dizzy 29. Nov 2004 14:22

Re: schnellerer Zugriff auf Tbitmap
 
Oder nutze die Graphics32-Lib. Dort ist ein Zugriff über die Pixel-Property mindestens bis annähernd so schnell wie mit (dem imho etwas unhandlichen) Scanline von TBitmap.

:thumb:

Ultimator 29. Nov 2004 14:23

Re: schnellerer Zugriff auf Tbitmap
 
Du könntest erst auf ein Bitmap im Speicher zeichnen und das dann wenn du fertig bist auf das anzuzeigende kopieren.

dizzy 29. Nov 2004 14:25

Re: schnellerer Zugriff auf Tbitmap
 
Zitat:

Zitat von Ultimator
Du könntest erst auf ein Bitmap im Speicher zeichnen und das dann wenn du fertig bist auf das anzuzeigende kopieren.

...und trotzdem bleibt der Zugriff über Pixels unsäglich lahm. Das ist keine Lösung! (Aber ein guter Hinweis zu sauberem Umgang mit Bitmaps ;))

cumi 29. Nov 2004 14:32

Re: schnellerer Zugriff auf Tbitmap
 
Zitat:

Zitat von Ultimator
Du könntest erst auf ein Bitmap im Speicher zeichnen und das dann wenn du fertig bist auf das anzuzeigende kopieren.

das mach ich natürlich schon so :-) bei der paintbox mach ich natürlich den ganzen redraw von hand...

Luckie 29. Nov 2004 14:33

Re: schnellerer Zugriff auf Tbitmap
 
Zitat:

Zitat von cumi
Zitat:

Zitat von Ultimator
Du könntest erst auf ein Bitmap im Speicher zeichnen und das dann wenn du fertig bist auf das anzuzeigende kopieren.

bei der paintbox mach ich natürlich den ganzen redraw von hand...

Und warum? Kostet sehr viel Zeit. Kopier (BitBlt) doch das Bitmap im Speicher bei Bedarf (OnPaint) auf die Paintbox.

cumi 29. Nov 2004 14:48

Re: schnellerer Zugriff auf Tbitmap
 
Zitat:

Zitat von Luckie
Zitat:

Zitat von cumi
Zitat:

Zitat von Ultimator
Du könntest erst auf ein Bitmap im Speicher zeichnen und das dann wenn du fertig bist auf das anzuzeigende kopieren.

bei der paintbox mach ich natürlich den ganzen redraw von hand...

Und warum? Kostet sehr viel Zeit. Kopier (BitBlt) doch das Bitmap im Speicher bei Bedarf (OnPaint) auf die Paintbox.

hmm, also mach ich eigentlich so...
Ich berechne zuerscht jeden Pixel des Bitmaps und zeige den dan mit Canvas.Draw(0,0,Bitmap); in die Paintbox. Und natürlich auch beim Ereigniss onpaint....

SirThornberry 29. Nov 2004 14:49

Re: schnellerer Zugriff auf Tbitmap
 
pixels verwendet intern SetPixel und GetPixel. Wenn du SetPixel und GetPixel direkt aufrufst ist das ganze auch wieder eing gaaaaaaaaaaaaaaanz kleines bischen schneller

dizzy 29. Nov 2004 15:04

Re: schnellerer Zugriff auf Tbitmap
 
Hier mal der direkte Codevergleich VCL <-> Graphics32:

Die ist alles das was TCanvas für ein SetPixel macht/braucht:
Delphi-Quellcode:
procedure TCanvas.SetPixel(X, Y: Integer; Value: TColor);
begin
  Changing;
  RequiredState([csHandleValid, csPenValid]);
  Windows.SetPixel(FHandle, X, Y, ColorToRGB(Value));
  Changed;
end;

procedure TCanvas.RequiredState(ReqState: TCanvasState);
var
  NeededState: TCanvasState;
begin
  NeededState := ReqState - State;
  if NeededState <> [] then
  begin
    if csHandleValid in NeededState then
    begin
      CreateHandle;
      if FHandle = 0 then
        raise EInvalidOperation.CreateRes(@SNoCanvasHandle);
    end;
    if csFontValid in NeededState then CreateFont;
    if csPenValid in NeededState then CreatePen;
    if csBrushValid in NeededState then CreateBrush;
    State := State + NeededState;
  end;
end;

function SetPixel(DC: HDC; X, Y: Integer; Color: COLORREF): COLORREF; stdcall;
Umwandlungen, if-Clauses und jede Menge mehr - für jeden einzeln gesetzen Pixel! Zudem ein Call einer API-Funktion. Das ist nicht wirklich schlimm, aber im Vergleich mal das was ein TBitmap32 macht:
Delphi-Quellcode:
procedure TBitmap32.SetPixel(X, Y: Integer; Value: TColor32);
begin
  Bits[X + Y * Width] := Value;
end;
Was sieht schneller aus?

Btw: TCanvas.SetPixel direkt aufzurufen bringt imho so gut wie nix, da der Compiler die Properties eh beim Kompilieren auf die Funktionen umlenkt -> es ist einem direkten Funktionsaufruf gleichwertig.


\\edit: Kleine Zusatzinfo: Die G32 benutzt wo es geht, und so weit vorhanden MMX, 3DNow, SSE, SSE2. (Das kommt beim Überblenden von halbtransparenten Bitmaps und den ganzen Filten+Stretchen+Rotation gut zum Einsatz.)

cumi 6. Dez 2004 22:03

Re: schnellerer Zugriff auf Tbitmap
 
@dizzy:Vielen Dank für deine Info!!
Nun leider durchschau ich das ganze mit der Graphics32 noch nicht ganz. Wie kann ich die einsetzen bzw. welche Files benötige ich wirklich? Ich habe gesehen, dass diese ja aus über 10 Units besteht und sicherlich einiges kann was ich nicht brauche. Ich muss eigentlich fast nichts könnten. Das einzige was ich können muss ist ein Bild in Form eines Bitmaps auf dem RAM anzulegen. Es Pixelweise zu beschreieben und zwar mit TColor Werten. Die TColor-Werte weise ich so zu:
Delphi-Quellcode:
color:=(tmp shl 16)+(tmp shl 8)+tmp //in tmp steht immer eine Zahl zwischen 0 und 255 (normales RGB System)
geht das noch schneller? Also die shl und shr sind ja sicherlich was vom schnellsten... RGB kenn ich auch ist aber nicht ganz so schnell so viel ich weiss.
Danach möchte ich das Bild in einer Paintbox anzeigen. Dabei muss es teilweise noch gestrecht werden.
Das wäre eigentlich alles was ich machen muss. Es sollte natürlich so schnell wie möglich werden da dies relativ wichtig ist. Ich möchte die selbe Zuweisung dann noch für Filme benutzen und wenn ich das einige 1000Frames rechne spielt es schon eine Rolle ob ich eine Woche oder ein paar Stunde dran bin :-) EndProjekt: Ein Fraktalprogramm welches einen Film von einem Zoom rechnen kann.

Vielen Dank für eure Hilfe!!!!

dizzy 7. Dez 2004 04:37

Re: schnellerer Zugriff auf Tbitmap
 
Das was du brauchst ist recht einfach, und der Handhabung von TBitmap recht ähnlich. Du musst die Unit "GR32" einbinden, und ein "TBitmap32" als Offscreenbitmap erzeugen. Davon im Vorfeld auch gleich die größe setzen, ganz wie mit den normalen Bitmaps.

Jetzt kommt die G32 allerdings mit einem eigenen Farbformat her: "TColor32".
Aus der Hilfe zur G32:
Code:
Bits 32...24: Alpha
Bits 23...16: Red
Bits 15...8 : Green
Bits 7...0  : Blue
Also kannst du einzelne Pixel wie folgt bearbeiten:
Delphi-Quellcode:
var
  bmp: TBitmap32;
begin
  bmp := TBitmap32.Create;
  bmp.Width := 320;
  bmp.Height := 240;

  bmp.Pixels[100, 100] := Color32(RotAnteil, GrünAnteil, BlauAnteil);
  // oder mit Alphakanal
  bmp.Pixels[100, 100] := Color32(RotAnteil, GrünAnteil, BlauAnteil, AlphaWert);
  // oder ohne Umwandlung mit shifting (ist bei der G32 NICHT zwangsläufig schneller!)
  bmp.Pixels[100, 100] := (AlphaWert shl 24) or (RotAnteil shl 16) or (GrünAnteil shl 8) or BlauAnteil;
Um dieses Bitmap irgendwo hin zu zeichnen hat TBitmap32 diverse überladene Versionen von "TBitmap32.DrawTo". Eine Variante kann auf ein beliebiges HDC zeichnen, z.B. ein "TCanvas.Handle". Das dürfte für dich interessant werden.

Zitat:

Ein Fraktalprogramm welches einen Film von einem Zoom rechnen kann.
:gruebel: Klingt interessant, aber was hab ich mir drunter vorzustellen?

Hoffe das hilft!
Fabian

cumi 7. Dez 2004 07:02

Re: schnellerer Zugriff auf Tbitmap
 
Vielen Dank für deine Hilfe. Ich werds gleich mal ausprobieren. Was du dir darunter vorstellen sollt? Ähh also das Mandelbrotfraktal kennst du oder? jetzt kann man da ja reinzoomen indem man einen Rahmen zieht. Naja also ich möcht jetzt stufenlos ins Fraktal reinfliegen können :-) Mal schauen wies rauskommt :-) Ich komm mit dem schreiben von AVI-Files noch nicht ganz klar. Also ich hab mal den TAVIWriter angesehen. Doch den müste ich relativ stark umschreiben. Das erste Problem ist, dass der unter Delphi6 nicht läuft. Der Compiler bringt dort einenen Fehler so im Stil "Ausdruck gefunden aber then erwartet" mitten in einem Funktionsaufruf und der Courser steht an einem ort wo es sowieso nix hat. Naja ebenn die Rükwärtkompatibilität von Delphi :-) Das zweite und noch viel grösere Problem ist. Dass der in der Orginalversion eigentlich so arbeitet, dass man zuerst alle bilder in eine Tbitmap list reinläut und er sie erst dann anfängt auf die HDD zu schreiben. Ist für mich auch unbrauchbar weil ich keine 10GB Ram habe :-)
Naja mal schauen.... werd ich schon noch irgendwie hinkriegen...

dizzy 7. Dez 2004 07:26

Re: schnellerer Zugriff auf Tbitmap
 
Liste der Anhänge anzeigen (Anzahl: 1)
Mit Fraktalen hast du bei mir den richtigen Nerv getroffen :D (Siehe Anhang: Das war mein letztes größeres Projekt -> 3D-Julia Fraktale)

Der eigentliche Flaschenhals ist da allerdings weit weinger die Geschwindigkeit beim Zugriff auf das Bitmap, als viel mehr die Berechnungen selbst. Da kann ich dir meinen Hier im Forum suchenCQParser anbieten, bzw. die darin enthaltene Unit "QMath" die einige Methoden zum recht schnellen Rechnen mit komplexen Zahlen enthält.

Das Schreiben eines Videos habe ich bisher immer VirtualDub oder TMPGEnc überlassen, und einfach die Bitmaps auf Platte geschoben. Allerdings könnte dir das Hier im Forum suchenDSPack in dieser Richtung weiter helfen.

Viel Erfolg! Und wenn Fragen dazu sind: Ich bin eigentlich immer interessiert :)

Gruss,
Fabian

PS: Ääääähhh .mpg ist nicht als Anhang erlaubt... dann eben als .zip :?

cumi 7. Dez 2004 09:36

Re: schnellerer Zugriff auf Tbitmap
 
das sieht ja (sorry) verdammt gut aus! Mit 3D Fraktalen hab ich mich noch nie beschäftigt. Vielleicht komm ich darauf zurück, wenn ich mit den 2D Fraktalen fertig bin :-)
Zur berechnugn. Also hier mal den Code, welchen ich brauch um die Divergenze von einem Punkt zu berechenn:
Delphi-Quellcode:
  TComplex=record
    r,i:Extended;
  end;
(...)
function TFrmMain.CalcDivMandel(x,y:Extended):Integer;
var
  z1,z2:TComplex;
  h1,h2:Extended;
  i   :Integer;
begin
  z1.r:=0;
  z1.i:=0;
  i  :=0;
  repeat
    h1  :=z1.r*z1.r;
    h2  :=z1.i*z1.i;
    z2.r:=h1-h2      +x;
    z2.i:=2*z1.r*z1.i+y;
    z1:=z2;
    inc(i);
  until (i>=steps) or ((h1+h2)>4);
  result:=i;
end;
Nun also ich hab das ganze mit der GR32 Unit einmal ausprobiert. Und ich muss sagen... kein vergleich viel schneller. Nur leider versteh ich das mit dem Alpha Teil des TColor32 Typs noch nicht ganz. Für was ist der gut? Kann man den auch weglassen? Denn momentan hab ich noch das Problem, das meine Bitmaps vielviel grösser werden als sie vorhin waren. Dies ist relativ verherend da ich ja nicht belibig Ram habe....

Nun nochmals eine kurze Frage. Du sagtest du überlässt das "Filmmachen" an Virtualdub etc. Wie funktioniert das denn bei dir genau? Also Virtualdub kenn ich relativ gut. Ich benutzte es häufig zum umcodieren von Filmen. Jetzt speicherst du einfach alle Frames als Bitmap auf die HDD?

Danke, Greez cumi

dizzy 7. Dez 2004 11:36

Re: schnellerer Zugriff auf Tbitmap
 
Zitat:

Zitat von cumi
Also hier mal den Code, welchen ich brauch um die Divergenze von einem Punkt zu berechenn:
Delphi-Quellcode:
  TComplex=record
    r,i:Extended;
  end;
(...)
function TFrmMain.CalcDivMandel(x,y:Extended):Integer;
var
  z1,z2:TComplex;
  h1,h2:Extended;
  i   :Integer;
begin
  z1.r:=0;
  z1.i:=0;
  i  :=0;
  repeat
    h1  :=z1.r*z1.r;
    h2  :=z1.i*z1.i;
    z2.r:=h1-h2      +x;
    z2.i:=2*z1.r*z1.i+y;
    z1:=z2;
    inc(i);
  until (i>=steps) or ((h1+h2)>4);
  result:=i;
end;

Na das sieht doch recht gut aus! Wenn du auf die Genauigkeit verzichten kannst: Double ist deutlich schneller als Extended. Aber grad für einen Zoom kann die Genauigkeit interessant werden (ich selbst hab bei immens starkem Zoom auch schon mal das "Ende von Double" gesehen :)).

Zitat:

Zitat von cumi
Nun also ich hab das ganze mit der GR32 Unit einmal ausprobiert. Und ich muss sagen... kein vergleich viel schneller. Nur leider versteh ich das mit dem Alpha Teil des TColor32 Typs noch nicht ganz. Für was ist der gut? Kann man den auch weglassen? Denn momentan hab ich noch das Problem, das meine Bitmaps vielviel grösser werden als sie vorhin waren. Dies ist relativ verherend da ich ja nicht belibig Ram habe....

Den Alphateil kanst du ganz weg lassen, ja. Der sollte dann imho auf 255 gesetzt werden. Der wird erst interessant wenn du mehrere Bitmaps halbtransparent überlagern möchtest. Allerdings kann man ihn nicht ganz weg lassen, d.h. ein Pixel wird immer volle 32 Bit beanspruchen. Deshalb ja auch Graphics32 ;).
Die gesamte Sequenz im RAM zu halten ist imho ohnehin nicht so glücklich. Über Chunks von so 10 bis 20 Bitmaps im Speicher kann man reden, die dann in einem Schwupps geschrieben werden, aber ich hab jedes Bitmap direkt nach Fertigstellung weggeschrieben und fertig.

Zitat:

Zitat von cumi
Nun nochmals eine kurze Frage. Du sagtest du überlässt das "Filmmachen" an Virtualdub etc. Wie funktioniert das denn bei dir genau? Also Virtualdub kenn ich relativ gut. Ich benutzte es häufig zum umcodieren von Filmen. Jetzt speicherst du einfach alle Frames als Bitmap auf die HDD?

Japp, genau so :)
Einfach mit aufsteigender Nummereierung benennen (z.B. frac0001.bmp; frac0002.bmp; ...; fracXXXX.bmp), und VirtualDub (und auch TMPGEnc) erkennen mit Öffnen des ersten Bildes der Sequenz dass es auch eine Sequenz ist, und behandelt es wie ein Video.
Ist zunächst mal die einfachere Variante während man sich noch mit den "wichtigen" Dingen rumplagen muss 8).

Gruss,
Fabian

cumi 7. Dez 2004 15:44

Re: schnellerer Zugriff auf Tbitmap
 
Zitat:

Zitat von dizzy
Na das sieht doch recht gut aus! Wenn du auf die Genauigkeit verzichten kannst: Double ist deutlich schneller als Extended. Aber grad für einen Zoom kann die Genauigkeit interessant werden (ich selbst hab bei immens starkem Zoom auch schon mal das "Ende von Double" gesehen :)).

Jo wenn du mal so richtig reinzoomen willst kommst du mit den Double wirklich an den Anschlag... Und viel langsamer wirds ja mit Extended wahrscheinlich auch nicht sein, oder?

Zitat:

Zitat von dizzy
Den Alphateil kanst du ganz weg lassen, ja. Der sollte dann imho auf 255 gesetzt werden. Der wird erst interessant wenn du mehrere Bitmaps halbtransparent überlagern möchtest. Allerdings kann man ihn nicht ganz weg lassen, d.h. ein Pixel wird immer volle 32 Bit beanspruchen. Deshalb ja auch Graphics32 ;).
Die gesamte Sequenz im RAM zu halten ist imho ohnehin nicht so glücklich. Über Chunks von so 10 bis 20 Bitmaps im Speicher kann man reden, die dann in einem Schwupps geschrieben werden, aber ich hab jedes Bitmap direkt nach Fertigstellung weggeschrieben und fertig.

Äh also bis jetzt hab ich ihn einfach immer gar nicht berücksichtigt. Daher wird er höchstwahrscheinlich auf 0 stehen... Funktioniert aber trotzdem. Kann aber auch sein das die Funktion Color32 den Alphawert automatisch auf 255 setz.
Nun du sagtest dieser werde für die Transparenz benutz. Wie funktioniert das? Mir ist gleich die Idee gekommen, dass ich eigentlcih übergänge von einer in die andere Farbe so rechnen könnte. Äh also mal eine Idee wie ich mir vorstellen könnte wies gehen könnte :-) Kann man einfach zuerst was zeichen, sprich einen Pixel einfärben mit dem Alphawert 255 und danach den selben Pixel nochmals überschreiben allerdings mit einem Alphawert von zb. 128 und dann er der Pixel schlussentlich den Mittelwert? Naja war nur so eine Idee :???:

Zitat:

Zitat von dizzzy
Zitat:

Zitat von cumi
Nun nochmals eine kurze Frage. Du sagtest du überlässt das "Filmmachen" an Virtualdub etc. Wie funktioniert das denn bei dir genau? Also Virtualdub kenn ich relativ gut. Ich benutzte es häufig zum umcodieren von Filmen. Jetzt speicherst du einfach alle Frames als Bitmap auf die HDD?

Japp, genau so :)
Einfach mit aufsteigender Nummereierung benennen (z.B. frac0001.bmp; frac0002.bmp; ...; fracXXXX.bmp), und VirtualDub (und auch TMPGEnc) erkennen mit Öffnen des ersten Bildes der Sequenz dass es auch eine Sequenz ist, und behandelt es wie ein Video.
Ist zunächst mal die einfachere Variante während man sich noch mit den "wichtigen" Dingen rumplagen muss 8).

Ah supi, wusste nicht das dies so einfach geht :-) Naja wie soll man schno auf die Ideekommen eine *.bmp Datei mit VirtualDub zu laden....:gruebel:

------------------
Nun hab ich aber trotzdem nochmals eine Frage. Also irgendwas mach ich da noch nicht ganz richtig habe ich bemerkt. Es sind nicht einfach TBitMap32 die mehr Stack brauchen, nein ich brauche wenn ich das selbe nochmals rechne und eigentlich nicht weitere TBitMaps erzeuge (mach ich dann auch teilweise in einer doppeltverlinkten Liste. Seit ich dieses System kenne brauch ich es wo es nur irgendwie einbisschen Sinn macht weil mich die Geschwindigkeit und die Bedienung fast vom Stuhl gehauen hat :P ).
Ich überschreibe dabei allerdings ein vorhandenes TBitMap immer wieder. Nun der fehler muss wohl dabei liegen.
Ich mache dies so:
Delphi-Quellcode:
  img:=TBitmap32.Create;  //img ist vom Typ TBitMap32
  img.Width:=sRef.dx;
  img.Height:=sRef.dy;
Ich hab dann mal zum probieren immernoch vor dem TBitmap32.Create img.free aufgerufen, was allerdings keine Abhilfe schuf.
Iregdnwer eine Idee was da sonst noch schieflaufen könnte??

Ah ja und gibts kei Tool von Delphi her welches einem anzeigt wo wieviel Speicher gebraucht wird? Ich benutze bis jetzt (ich weiss, dass es nichts dümmeres gibt :-)) den Taskmanager von WinXP. Ich zweifle jedoch an dessen Richtigkeit.....

Vielen Dank für eure Hilfe! Greez cumi

dizzy 7. Dez 2004 18:03

Re: schnellerer Zugriff auf Tbitmap
 
Zitat:

Zitat von cumi
Jo wenn du mal so richtig reinzoomen willst kommst du mit den Double wirklich an den Anschlag... Und viel langsamer wirds ja mit Extended wahrscheinlich auch nicht sein, oder?

Immerhin ca. Faktor 3 (bei einfacher Addition). Hab hier mal einen Test mit so ziemlich allen Typen gemacht.

Zitat:

Zitat von cumi
Äh also bis jetzt hab ich ihn einfach immer gar nicht berücksichtigt. Daher wird er höchstwahrscheinlich auf 0 stehen... Funktioniert aber trotzdem. Kann aber auch sein das die Funktion Color32 den Alphawert automatisch auf 255 setz.

Wenn du bei Color32() nur 3 Parameter übergibst, dann ist Alpha per default auf 255 (= voll Deckend)

Zitat:

Zitat von cumi
Nun du sagtest dieser werde für die Transparenz benutz. Wie funktioniert das? Mir ist gleich die Idee gekommen, dass ich eigentlcih übergänge von einer in die andere Farbe so rechnen könnte. Äh also mal eine Idee wie ich mir vorstellen könnte wies gehen könnte :-) Kann man einfach zuerst was zeichen, sprich einen Pixel einfärben mit dem Alphawert 255 und danach den selben Pixel nochmals überschreiben allerdings mit einem Alphawert von zb. 128 und dann er der Pixel schlussentlich den Mittelwert? Naja war nur so eine Idee :???:

Das geht, allerdings nicht via TBitmap32.Pixels[], da du damit den Pixel incl. Alphawert ganz neu setzt. Du müsstest dir ein zweites TBitmap32 machen, und dort dein zu überblendendes Bitmap mit Transparenzen rein schreiben. (TBitmap32.BlendMode muss dann auf dmBlend gesetzt werden.) Dann kannst du das mit DrawTo() auf das erste drauf malen, mit Berücksichtigung der Alphawerte.

Zitat:

Zitat von cumi
Ah supi, wusste nicht das dies so einfach geht :-) Naja wie soll man schno auf die Ideekommen eine *.bmp Datei mit VirtualDub zu laden....:gruebel:

:mrgreen: Ich habs einfach ausprobiert, da es in der Filterliste des Open-Dialogs steht ;)

Zitat:

Zitat von cumi
Nun hab ich aber trotzdem nochmals eine Frage. Also irgendwas mach ich da noch nicht ganz richtig habe ich bemerkt. Es sind nicht einfach TBitMap32 die mehr Stack brauchen, nein ich brauche wenn ich das selbe nochmals rechne und eigentlich nicht weitere TBitMaps erzeuge (mach ich dann auch teilweise in einer doppeltverlinkten Liste. Seit ich dieses System kenne brauch ich es wo es nur irgendwie einbisschen Sinn macht weil mich die Geschwindigkeit und die Bedienung fast vom Stuhl gehauen hat :P ).
Ich überschreibe dabei allerdings ein vorhandenes TBitMap immer wieder. Nun der fehler muss wohl dabei liegen.
Ich mache dies so:
Delphi-Quellcode:
  img:=TBitmap32.Create;  //img ist vom Typ TBitMap32
  img.Width:=sRef.dx;
  img.Height:=sRef.dy;
Ich hab dann mal zum probieren immernoch vor dem TBitmap32.Create img.free aufgerufen, was allerdings keine Abhilfe schuf.
Iregdnwer eine Idee was da sonst noch schieflaufen könnte??

Das ständige Freigeben und Neuerstellen ist imho sehr unsauber, zumal der Speichermanager von Delphi dazu neigt einmal alloziierten Speicher nicht umgehend an Windows zurück zu geben (zur Geschwindigkeitsoptimierung). Nimm besser eine einzige Variable vom Typ TBitmap32 und mache vor dem Neuzeichnen ein Clear(Color32(0,0,0));
btw: Du schreibst "Stack". Objekte werden doch aber auf dem Heap angelegt, oder? :gruebel:

Zitat:

Zitat von cumi
Ah ja und gibts kei Tool von Delphi her welches einem anzeigt wo wieviel Speicher gebraucht wird? Ich benutze bis jetzt (ich weiss, dass es nichts dümmeres gibt :-)) den Taskmanager von WinXP. Ich zweifle jedoch an dessen Richtigkeit.....

Ich habe hier schon öfters Hier im Forum suchenmemproof gelesen. Benutzt hab ich es allerdings noch nicht.

Arrividetschi :)
Fabian

cumi 7. Dez 2004 20:56

Re: schnellerer Zugriff auf Tbitmap
 
Zitat:

Zitat von dizzy
Immerhin ca. Faktor 3 (bei einfacher Addition). Hab hier mal einen Test mit so ziemlich allen Typen gemacht.

Hmm, hab jetzt mal alles in Double umgewandelt und ich hol ca. einen Faktor 2 an Zeit raus. Daher denke ich werd ich von jetzt an Double benutzen. Und wenn ichs dann doch mal noch genauer haben will ist es ja ein kleines das Programm nochmals schnell mit Extended zu compilieren.
Mal noch eine Frage. Was machst du eigentlich beruflich? Informatik ist nicht nur dein Hobby, oder? Ich bin immerwieder aufs neue erstaunt wie genau, dass du über all diese Dinge bescheid weisst.... Und hier gleich noch der absolut passende Test :-)

Zitat:

Zitat von dizzy
Das geht, allerdings nicht via TBitmap32.Pixels[], da du damit den Pixel incl. Alphawert ganz neu setzt. Du müsstest dir ein zweites TBitmap32 machen, und dort dein zu überblendendes Bitmap mit Transparenzen rein schreiben. (TBitmap32.BlendMode muss dann auf dmBlend gesetzt werden.) Dann kannst du das mit DrawTo() auf das erste drauf malen, mit Berücksichtigung der Alphawerte.

Kann ich mal ausprobieren, ja.
Jetzt bin ich gleich an einem Problem angelangt das eigentlich auch hierhinein gehört und zwar:
Ich habe zwei Farben (TColor32). Nun möchte ich einen Übergang von der einen in die andere berechnen. Ich nehme an, dass es hierfür von der GR32 auch Möglichkeiten gibt. Ich hab sie leider nur noch nicht gefunden :-)

Zitat:

Zitat von dizzy
Das ständige Freigeben und Neuerstellen ist imho sehr unsauber, zumal der Speichermanager von Delphi dazu neigt einmal alloziierten Speicher nicht umgehend an Windows zurück zu geben (zur Geschwindigkeitsoptimierung). Nimm besser eine einzige Variable vom Typ TBitmap32 und mache vor dem Neuzeichnen ein Clear(Color32(0,0,0));

Äh also das geht leider nicht weil ich immerwieder die Gröse ändere, also .Width und .Height neu setze (resize des Forms)...

Zitat:

Zitat von dizzy
btw: Du schreibst "Stack". Objekte werden doch aber auf dem Heap angelegt, oder? :gruebel:

äh jo stimmt, so genau hab ichs nicht genommen :-) Sagen wir einfach mal im Speicher :-)


Zitat:

Zitat von dizzy
Zitat:

Zitat von cumi
Ah ja und gibts kei Tool von Delphi her welches einem anzeigt wo wieviel Speicher gebraucht wird? Ich benutze bis jetzt (ich weiss, dass es nichts dümmeres gibt :-)) den Taskmanager von WinXP. Ich zweifle jedoch an dessen Richtigkeit.....

Ich habe hier schon öfters Hier im Forum suchenmemproof gelesen. Benutzt hab ich es allerdings noch nicht.

Werd ich auch mal ausprobieren... Wäre schon noch schön ein genaueres Abbild des Speichers zu sehen.


Zum Schluss möcht ich dir, Fabian, nochmals ganz herzlich danken für deine Geduld mir alle Fragen zu beantworten. Bin ich echt mega super froh :-) Denn wenn ich das alles in Büchern oder im Netz zusammensuchen müsste würd ichs glaub ich gar nicht finden oder dann hätte ich ein halbes Jahr :-)

Greez cumi

dizzy 7. Dez 2004 21:14

Re: schnellerer Zugriff auf Tbitmap
 
Zitat:

Zitat von cumi
Mal noch eine Frage. Was machst du eigentlich beruflich? Informatik ist nicht nur dein Hobby, oder? Ich bin immerwieder aufs neue erstaunt wie genau, dass du über all diese Dinge bescheid weisst.... Und hier gleich noch der absolut passende Test :-)

Ich bin "beruflich" Student der Informatik. Allerdings hat dieses mit dem Thema hier nicht sehr viel zu tun - das ist eigentlich 100% privates Interesse und jahrelang aufkummuliertes (Halb-)Wissen :lol:

Zitat:

Zitat von cumi
Jetzt bin ich gleich an einem Problem angelangt das eigentlich auch hierhinein gehört und zwar:
Ich habe zwei Farben (TColor32). Nun möchte ich einen Übergang von der einen in die andere berechnen. Ich nehme an, dass es hierfür von der GR32 auch Möglichkeiten gibt. Ich hab sie leider nur noch nicht gefunden :-)

Das macht dir die G32 nicht ganz so einfach wie du es gerne hättest ;). Das Zauberwort heisst hier lineare Interpolation, und zum Mischen zweier Farben dürftest du hier in der DP auch einiges finden.
Allerdings bringt die G32 eine nette Routine mit, die das Mischen recht effizient (weil mit MMX) umsetzt: "Combine(X, Y, W: TColor32): TColor32"
Auszug aus der Hilfe:
Zitat:

Returns the color with components calculated as linear interpolation between X and Y colors. The W parameter, which sholuld be in [0..255] range, specifies the weight of the first color (X). The alpha channel is interpolated as well.
Wichtig ist dabei, dass du nachher die Prozedur "EMMS;" aufrufst bevor du wieder mit normalen Fließkommarechnungen anfängst, da sonst die CPU auf MMX geschaltet bleibt, und keine normalen FLOPs mehr berechnet.

Zitat:

Zitat von cumi
Äh also das geht leider nicht weil ich immerwieder die Gröse ändere, also .Width und .Height neu setze (resize des Forms)...

Na dan ändere doch einfach die Größe ;). Dazu musst du das Bitmap ja nicht neu erstellen! (btw: TBitmap32.SetSize(X, Y) ist etwas effizienter als das einzelne Zuweisen an Width und Height.)

Zitat:

Zitat von cumi
äh jo stimmt, so genau hab ichs nicht genommen :-) Sagen wir einfach mal im Speicher :-)

Oki :P

Zitat:

Zitat von cumi
Zum Schluss möcht ich dir, Fabian, nochmals ganz herzlich danken für deine Geduld mir alle Fragen zu beantworten. Bin ich echt mega super froh :-) Denn wenn ich das alles in Büchern oder im Netz zusammensuchen müsste würd ichs glaub ich gar nicht finden oder dann hätte ich ein halbes Jahr :-)

Keine Ursache. Was meinst du wie viel Wissen ich diesem Forum schon zu verdanken hab :).
Macht ja Spaß!

Cu,
Fabian

cumi 8. Dez 2004 16:46

Re: schnellerer Zugriff auf Tbitmap
 
in welcher unit ist die Combine(X, Y, W: TColor32) enthalten?

dizzy 8. Dez 2004 17:02

Re: schnellerer Zugriff auf Tbitmap
 
Laut der Hilfe-Datei (*mitdemzaunwink* ;)) in der "GR32_Blend".

cumi 8. Dez 2004 17:13

Re: schnellerer Zugriff auf Tbitmap
 
supi, habs jetzt geschafft, allerdings mit der blendfunktion.... laut hilfe passt die noch genauer zu meinem problem... oder ist die viel langsamer?

dizzy 8. Dez 2004 17:38

Re: schnellerer Zugriff auf Tbitmap
 
Die könnte u.U. sogar schneller sein. Das weiss ich grad nicht so genau.
Der Unterschied zwischen den beiden ist ja:
Combine mischt 2 Farben (incl. Alpha-Komponente) im Verhältnis W : (1-W)
Blend mischt 2 Farben (excl. Alpha-Komponente), dafür in einem Verhältnis wie es die Alpha-Komponente angibt.

Lösen lässt sich dein Problem prinzipiell mit beiden :).


\\edit: Diese ungewollten Grinser immer :D

cumi 8. Dez 2004 17:54

Re: schnellerer Zugriff auf Tbitmap
 
stimmt, jo naja ich machs jetzt mit blend... ist spezifisch für mein Problem direkter...
Und ich muss sagen, diese GrafikUnit ist wirklich ganz extrem leistungsstark!

cumi 8. Dez 2004 18:18

Re: schnellerer Zugriff auf Tbitmap
 
wenn isch schon am fragen bin, dann frag ich doch gleich weiter, denn ich bin schon bei meinem nächsten Problem angelangt. Gibt es eine Funktion, welche einem die Komplementärfarbe (Gegenfarbe) einer TColor32 berechnet?

dizzy 8. Dez 2004 21:01

Re: schnellerer Zugriff auf Tbitmap
 
Soooo schlecht ist die Hilfe zur G32 doch garnet :zwinker:

Invert() bzw. InvertRGB() invertieren dir ein ganzes TBitmap32. Einmal mit, und einmal ohne den Alphakanal mit zu invertieren.

Ansonsten ist zu einer Farbe "r, g, b" die Farbe "255-r, 255-g, 255-b" invers. Also so einfach selber zu machen, dass die G32 da nicht mal eine separate Funktion für bietet ;).

\\edit: Die Funktion ColorSub() könnte dir dabei helfen. Wenn du:
Delphi-Quellcode:
NewColor := ColorSub(Color32(255,255,255), Color(255,0,0));
bekommst du die Komplementärfarbe zu Rot. Sollte schneller sein, als es von Hand zu berechnen. Einfach die zu invertierende Farbe von Weiss subtrahieren.

Eichhoernchen 9. Dez 2004 22:01

Re: schnellerer Zugriff auf Tbitmap
 
*sabber* Fraktale, das ist eins der geilsten sachen die es gibt.

hab auch mal so nen Programm geschrieben was mandelbrote usw. backt.


Mit der TBitmap methode scanline kannste ne mandelbrotberechnung mit Pixles[x,y] so um die 10 seckunden verschnellern!

Auf delphi-source.de gibt es beispiele zu scanline

Delphi Source Scanline

Hoffe das hilft dir! Mir hat es das!

dizzy 9. Dez 2004 23:08

Re: schnellerer Zugriff auf Tbitmap
 
Öhm, glaub mir: Die G32 ist u.U. sogar noch schneller, und vor allem um Längen komfortabler als das Pointerrumgeschubse mit Scanline. Hab's bevor ich die G32 kannte auch mit Scanline gemacht, aber der Umstieg war mehr als richtig und einfach.
Zumal man mit der G32 auf einmal einen riesen Haufen an Möglichkeiten mehr hat: Layered Bitmaps, eingebautes Antialiasing mit verschiedenen Algos (man kann sogar Pixel auf Float-Koordinaten setzen, und die G32 übernimmt die Verteilung auf die 4 realen Pixel), volle Alphakanalunterstützung, haufenweise Optimierungen mit MMX, SSE(2), etc., und vieles vieles mehr.
Wer viel Grafik mit Delphi macht, dem kann ich die G32 einfach nur wärmstens an's Herz legen - Scanline ist nen Weisenkind dagegen ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:45 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-2025 by Thomas Breitkreuz