AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign 24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung
Thema durchsuchen
Ansicht
Themen-Optionen

24-Bit Bitmap um 90 grad drehen - Resourcen-Optimierung

Ein Thema von Harry Stahl · begonnen am 18. Okt 2020 · letzter Beitrag vom 23. Okt 2020
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.558 Beiträge
 
Delphi 12 Athens
 
#1

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

  Alt 18. Okt 2020, 22:22
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...
  Mit Zitat antworten Zitat
Renate Schaaf

Registriert seit: 25. Jun 2020
Ort: Lippe
114 Beiträge
 
Delphi 11 Alexandria
 
#2

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

  Alt 18. Okt 2020, 22:47
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
Renate
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.558 Beiträge
 
Delphi 12 Athens
 
#3

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

  Alt 18. Okt 2020, 23:01
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
Gerne. Was meinst Du mit nur 2 mal aufrufen?

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?
  Mit Zitat antworten Zitat
Amateurprofi

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

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

  Alt 19. Okt 2020, 00:41
@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;
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Renate Schaaf

Registriert seit: 25. Jun 2020
Ort: Lippe
114 Beiträge
 
Delphi 11 Alexandria
 
#5

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

  Alt 19. Okt 2020, 01:00
Zitat:
Gerne. Was meinst Du mit nur 2 mal aufrufen?
So in etwa:

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;
Renate
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.558 Beiträge
 
Delphi 12 Athens
 
#6

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

  Alt 19. Okt 2020, 01:39
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).
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.558 Beiträge
 
Delphi 12 Athens
 
#7

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

  Alt 19. Okt 2020, 01:43
@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.
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.558 Beiträge
 
Delphi 12 Athens
 
#8

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

  Alt 19. Okt 2020, 01:55
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...

Geändert von Harry Stahl (19. Okt 2020 um 01:58 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch
Online

Registriert seit: 11. Aug 2012
Ort: Essen
1.680 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#9

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

  Alt 19. Okt 2020, 08:08
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.
Thomas Mueller

Geändert von dummzeuch (19. Okt 2020 um 08:10 Uhr)
  Mit Zitat antworten Zitat
striderx

Registriert seit: 11. Feb 2007
Ort: Bergisch Gladbach
207 Beiträge
 
Delphi 10.4 Sydney
 
#10

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

  Alt 19. Okt 2020, 09:20
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;
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 16:58 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