![]() |
AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
Zitat:
|
AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
Liste der Anhänge anzeigen (Anzahl: 1)
Ich rufe Deine Funktion wie folgt auf:
GDIPRotateFlipBitmap (bm, Rotate90FlipY); In der Anlage siehst Du als Screenshot die Ausgangssituation und jeweils die Bilder mit Deiner Funktion gedreht, wenn es ein 24-Bit Bild ist und einmal als 32-Bit Bild. Bei dem 24-Bit-Bild wird ein falsches Ergebnis zurück geliefert... |
AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
Hallo Harry,
ich habe es gerade mehrfach ausprobiert - bei mir ist das Ergebnis immer einwandfrei. Das muss also an etwas anderem liegen. Ggf. an der Stelle, wo du die Bitmap in das Image überträgst? Mir fällt auch auf, dass das 32 bit-Bild größer ist als das Ursprungsbild und dass das 24 bit-Ergebnis einen zweiten, seitenverkehrten Kalenderblock enthält. Alles Gute Volker |
AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
Also das 32-Bit wirkt nur größer, da es schon (richtig) gedreht wurde.
Das 24-Bit wurde mit Deiner Funktion "gedreht", aber hat ersichtlich nicht funktioniert. Ich mache gleich mal zum Testen ein neues Miniprojekt und teste das mal... |
AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
Danke für die Idee mit den worker-threads, probier ich doch gleich mal aus!
Wenn man nur 2mal GetScanline aufruft, geht es auch schneller. Renate |
AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
[Nicht] Anliegend ein Testprojekt, es funktioniert weder unter Delphi XE7 (was ich derzeit noch für das Programm verwende), noch unter dem aktuellsten 10.4.1...
Wegen der Dateigröße von 14 MB (das 24-bit-Bild) musste ich das Demo kurz auf meine eigene Seite laden, lasse es solange drauf, bis Du entweder sagst, Du willst es Dir nicht ansehen oder dass Du es geladen hast: ![]() |
AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
Zitat:
Ich habe ja die Original-Routine von Doberenz schon um ca. 20% Speed gesteigert, indem ich das PEnd := Bm.scanline[bm.height-1]; vor die Schleife gesetzt habe und in der Schleife nur den gespeicherten Wert zuweisen muss. Aber "rowout := help.scanline [y];" brauche ich doch weiterhin und kann es nicht ersetzen. Oder? |
AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
@Harry:
Wenn du auf Performance aus bist, dann versuch doch mal folgendes. Sollte deutlich schneller sein. Achtung: Der 64Bit-Teil in CopyColumn24 ist ungetestet, weil das Projekt mit dem ich gerade herumspiele nicht 64Bit-fähig ist. Unter 32 Bit (mit relativ kleinen Bitmaps) ergibt meine Messung dass das doppelt so schnell läuft, wie die ursprüngliche Routine.
Delphi-Quellcode:
PROCEDURE CopyColumn24(PSource,PDest:Pointer; Count,LO:NativeInt);
asm {$IFDEF CPUX86}// RAX=PSource, RDX=PDest, RCX=Count, Stack=LO push ebx mov ebp,LO dec ecx @Loop: mov ebx,[eax] mov [edx],ebx add eax,ebp add edx,3 sub ecx,1 jnz @Loop mov bx,[eax] mov [edx],bx mov bl,[eax+2] mov [edx+2],bl pop ebx {$ELSE} // RCX=PSource, RDX=PDest, R8=Count, R9=LO dec r8 @Loop: mov eax,[rcx] mov [rdx],eax add rcx,r9 add rdx,3 sub r8,1 jnz @Loop mov ax,[rcx] mov [rdx],ax mov al,[rcx+2] mov [rdx+2],al {$ENDIF} end;
Delphi-Quellcode:
PROCEDURE RotateRight24(Bmp:TBitmap);
var W,H,Y,LoSource,LoDest:NativeInt; PSource,PDest:PByte; Dest:TBitmap; begin W:=Bmp.Height; H:=Bmp.Width; PSource:=Bmp.ScanLine[W-1]; LoSource:=NativeInt(Bmp.ScanLine[W-2])-NativeInt(PSource); Dest:=TBitmap.Create; Dest.PixelFormat:=pf24bit; Dest.SetSize(W,H); PDest:=Dest.ScanLine[0]; LoDest:=NativeInt(Dest.ScanLine[1])-NativeInt(PDest); for Y:=H-1 downto 0 do begin CopyColumn24(PSource,PDest,W,LoSource); Inc(PSource,3); Inc(PDest,LoDest); end; Bmp.Assign(Dest); Dest.free; end; |
AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
Zitat:
Delphi-Quellcode:
procedure Drehe90Rechts24NurPointers(bm: TBitmap);
var P, Pend, Pdest: PRGBTriple; x, y, b, h: Integer; RowOut: PByte; help: TBitmap; var Offs, OffsDest: NativeInt; begin help := TBitmap.create; help.pixelformat := pf24bit; b := bm.height; h := bm.width; help.SetSize(b, h); RowOut := help.scanline[0]; Pend := bm.scanline[bm.height - 1]; Offs := ((h * 24 + 31) and not 31) div 8; OffsDest := ((b * 24 + 31) and not 31) div 8; for y := 0 to h - 1 do begin P := Pend; inc(P, y); Pdest := PRGBTriple(RowOut); for x := 0 to b - 1 do begin Pdest^ := P^; inc(Pdest); inc(NativeInt(P), Offs); end; dec(RowOut, OffsDest); end; bm.Assign(help); help.free; end; |
AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
Nur Pointer bringt auch noch mal 500 ms. Hier auf dem Entwicklungs-PC in der virtuellen Maschine wird das große Bild mit Deiner Variante in ca. 5 bis 5,5 Sek. gedreht.
Mit meiner ursprünglichen Variante und den Workerthreads geht's in ca. 3 Sekunden (auf meinem Vertriebs-PC (I5-Prozessor) geht's in ca. 1 Sekunde). Im Vergleich zu MS-Paint: das braucht auf den Entwicklungs-PC 20 Sekunden um das Bild zu drehen, auf dem Vertreibs-PC 8 Sekunden (und verbraucht nach 1 mal Drehen 4.5 GB Arbeitsspeicher, mein Programm mit Undo-Aktiv ca. 2 GB). |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:03 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