Delphi-PRAXiS
Seite 3 von 5     123 45      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung (https://www.delphipraxis.net/205798-24-bit-bitmap-um-90-grad-drehen-resourcen-optimierung.html)

Harry Stahl 19. Okt 2020 01:43

AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
 
Zitat:

Zitat von Amateurprofi (Beitrag 1475699)
@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;

Oh, habe ich gerade erst gesehen (manchmal überholen sich die Beiträge irgendwie), werde ich mir morgen Abend auf jeden Fall auch noch mal ansehen und mich melden.

Harry Stahl 19. Okt 2020 01:55

AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
 
Zu guter letzt noch die Feststellung, dass sich die WorkerThreads eigentlich nur bei ganz großen Dateien lohnen. Bei kleineren Bitmaps (alles so unter 4000 x 4000) ist der Thread-Verwaltungsaufwand wohl zu hoch, da ist das z.T. auch schon mal langsamer als nur eine Routine. Da man auf alle Worker-Threads warten muss, bevor man das Ergebnis zuweist, kann es sich evtl. auch etwas in die Länge ziehen, wenn eine CPU zu sehr belastet ist und daher einen Thread etwas blockiert..

Vielleicht sollte ich auch nicht alle zur Verfügung stehenden CPUs nutzen, sondern immer 1 oder 2 weniger, damit so evtl. die restlichen voll für meine Berechnungsaufgaben zur Verfügung stehen.

Muss ich morgen noch mal testen...

striderx 19. Okt 2020 06:55

AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
 
Zitat:

Zitat von Harry Stahl (Beitrag 1475696)
[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:

https://www.hastasoft.de/GDITest.zip

Da ich hier immer mit quadratischen Bildern arbeite, ist mir das bislang nicht aufgefallen: Man muss bei nicht quadratischen Vorlagen natürlich auch die Dimensionen der Ziel-Bitmap entsprechend anpassen.

Delphi-Quellcode:
function GDIPRotateFlipBitmap(ABitmap: tBitmap; Mode: RotateFlipType): Boolean;

var
  BM:        tBitmap;
  GR:        tGPGraphics;
  AGPBitmap: tGPBitmap;
  AStatus:   Status;
  W:         Integer;

begin
  if Mode = RotateNoneFlipNone then begin
     Result := True;
     Exit;
  end;
 
  BM := tBitmap.Create;                                                        
  BM.Assign(ABitmap);                                                          
  AGPBitmap := tGPBitmap.Create(BM.Handle, 0);                                
 
  AGPBitmap.RotateFlip(Mode);
> if ABitmap.Width <> ABitmap.Height then begin
>    W := ABitmap.Width;
>    ABitmap.Width := ABitmap.Height;
>    ABitmap.Height := W;
> end;
  GR := tGPGraphics.Create(ABitmap.Canvas.Handle);
  GR.DrawImage(AGPBitmap, 0, 0);
  AStatus := GR.GetLastStatus;
 
  Result := (AStatus = OK);
 
  AGPBitmap.Free;
  BM.Free;
  GR.Free;
end;
Viel Spaß beim weiteren Basteln.

venice2 19. Okt 2020 07:59

AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
 
Zitat:

Viel Spaß beim weiteren Basteln.
Dito!

Delphi-Quellcode:
procedure TForm34.Button1Click(Sender: TObject);
var
  bm: Tbitmap;
  Start, Stop: Cardinal;
begin
  Start := GetTickCount;
  bm := TBitmap.Create;
  bm.Assign(image1.Picture.Bitmap);
//  GDIPRotateFlipBitmap (bm, Rotate90FlipY);
  bm := FastAARotatedBitmap(bm.Handle, 90.0, TColor($FFFF),
    true, true, false, 1.0);
  Image2.Picture.Bitmap.Assign(bm);
  Image2.Refresh;
  Stop := GetTickCount - Start;
  Caption := Format('%d ms', [Stop]); // 656 ms ..
end;

dummzeuch 19. Okt 2020 08:08

AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
 
Zitat:

Zitat von Harry Stahl (Beitrag 1475697)
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.

Du kannst Die Adressen der Zeilen jeweils selbst berechnen. Das sind dann nur noch zwei Aufrufe von Scanline[]. Das macht einen riesigen Unterschied.

Ich habe darüber vor einiger Zeit mal geblogt.

Edit: Ich sehe gerade, Renate Schaaf hatte das auch schon geschrieben, incl. Code. Sorry für das Duplikat.

striderx 19. Okt 2020 09:20

AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
 
Nachtrag der Vollständigkeit halber :)

Delphi-Quellcode:
function GDIPRotateFlipBitmap(ABitmap: tBitmap; Mode: RotateFlipType): Boolean;

var
  BM:        tBitmap;
  GR:        tGPGraphics;
  AGPBitmap: tGPBitmap;
  AStatus:   Status;
  W:         Integer;

begin
  if Mode = RotateNoneFlipNone then begin
     Result := True;
     Exit;
  end;
 
  BM := tBitmap.Create;    
  BM.Assign(ABitmap);      
  AGPBitmap := tGPBitmap.Create(BM.Handle, 0);
 
  AGPBitmap.RotateFlip(Mode);
 
  if (ABitmap.Width <> ABitmap.Height) and
>    (Mode in [Rotate90FlipNone, Rotate270FlipNone,
>              Rotate90FlipX, Rotate270FlipX,
>              Rotate90FlipY, Rotate270FlipY,
>              Rotate90FlipXY, Rotate270FlipXY]) then begin
     W := ABitmap.Width;
     ABitmap.Width := ABitmap.Height;
     ABitmap.Height := W;
  end;
 
  GR := tGPGraphics.Create(ABitmap.Canvas.Handle);
  GR.DrawImage(AGPBitmap, 0, 0);
  AStatus := GR.GetLastStatus;
 
  Result := (AStatus = OK);
 
  AGPBitmap.Free;
  BM.Free;
  GR.Free;
end;

haentschman 19. Okt 2020 09:26

AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
 
Zitat:

der Vollständigkeit halber
Vollständig wäre es mit try/finally Blocks... :duck:

:zwinker:

Jens01 19. Okt 2020 10:03

AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
 
Wenn ich das eben richtig nachgelesen habe, kann man für Bitmap-Veränderungen auch die Intel-Prozessoren direkt ansteuern, was der Bearbeitung noch mal Schub verleihen soll.
Intel Integrated Performance Primitives for Intel Architecture
Hier ist ein Header.
Ich weiß nur nicht genau, wie man den Header ansteuert. :shock:

striderx 19. Okt 2020 10:07

AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
 
Zitat:

Zitat von haentschman (Beitrag 1475718)
Zitat:

der Vollständigkeit halber
Vollständig wäre es mit try/finally Blocks... :duck:

:zwinker:

Grundsätzlich richtig, aber an welcher Stelle meinst du denn, dass hier eine Exception 'durchschlägt'?. Seitens GDI+ m. W. nicht, da kann man nur mit GetLastStatus den Status der letzten Operation abfragen. Könnte man natürlich verschachteln mit mehreren
Delphi-Quellcode:
if AStatus = OK
, aber bei dem Größenbug von FlipRotate ist der Status OK. Und selbst wenn man das tBitmap.Create wegläßt, knallt es nicht.

Aber vielleicht übersehe ich ja etwas.

venice2 19. Okt 2020 11:24

AW: 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
 
Zitat:

Zitat von striderx (Beitrag 1475725)
Zitat:

Zitat von haentschman (Beitrag 1475718)
Zitat:

der Vollständigkeit halber
Vollständig wäre es mit try/finally Blocks... :duck:

:zwinker:

Grundsätzlich richtig, aber an welcher Stelle meinst du denn, dass hier eine Exception 'durchschlägt'?. Seitens GDI+ m. W. nicht, da kann man nur mit GetLastStatus den Status der letzten Operation abfragen. Könnte man natürlich verschachteln mit mehreren
Delphi-Quellcode:
if AStatus = OK
, aber bei dem Größenbug von FlipRotate ist der Status OK. Und selbst wenn man das tBitmap.Create wegläßt, knallt es nicht.

Aber vielleicht übersehe ich ja etwas.

Alles gut und schön.
Nur die Funktion im GDITest Projekt spiegelt das Bild es wird nicht korrekt dargestellt.
Delphi-Quellcode:
GDIPRotateFlipBitmap (bm, Rotate90FlipY);


Delphi-Quellcode:
GDIPRotateFlipBitmap (bm, Rotate90FlipNone);

wäre korrekt!
Ist zwar schnell aber das Ergebnis zu meiner Funktion ist nur schlecht.
Vergleiche beide Bilder das von mir hochgeladene und das hier.
Das vergleichen kann man hier vergessen da die Konvertierung des Bitmap (*.png) zu *.jpg (Hier im Forum) das original verfälscht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:38 Uhr.
Seite 3 von 5     123 45      

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