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
Benutzerbild von Harry Stahl
Harry Stahl

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

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

  Alt 18. Okt 2020, 19:39
Ich habe in meinem Programm eine Performance-Test Anzeige eingebaut (die man aktivieren muss) und habe Deine Funktion mal im Vergleich getestet:

Beide Funktionen sind in etwa gleich schnell. Wobei die GDI-Funktionen offensichtlich nur mit 32-Bit-Dateien funktionieren, hier muss ich also Datei erst in 32-Bit umwandeln, verbrauche dafür also schon mal mehr Arbeitsspeicher. Im Vergleich zu der 24-Bit-Drehung ist "meine" Funktion bei 660 Mio. Pixeln ca. 500 ms schneller (insgesamt hier auf dem PC ca. 6 Sekunden).

Aber man kann (zumindest mit der 64-Bit-Version) auch die 660 bzw. über 900 Mio. Pixel mit der GDI-Funktion benutzen, hier konnte ich keine Einschränkung feststellen.

Ich werde allerdings die Drehfunktion noch (wenn das geht) in eine Funktion mit Workerthreads umgestalten, wo jede CPU einen Teilbereich bearbeitet.

Das bringt echt noch mal Speed: Für die Funktion zur Änderung der Helligkeit habe ich das schon mal gemacht, während die Funktion für das oben erwähnte große Bild bei einer CPU z.B. 1,6 Sekunden braucht, um die Helligkeit zu ändern, geht es mit den Workerthreads (mit TTask) (ja nach Anzahl der CPUS) mit 6 CPUS z.B. in 300 MS. Das ist schon ein spürbarer Unterschied....
  Mit Zitat antworten Zitat
striderx

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

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

  Alt 18. Okt 2020, 20:15
Wobei die GDI-Funktionen offensichtlich nur mit 32-Bit-Dateien funktionieren,
Wie kommst du denn darauf? Ich arbeite hier nur mit 24 Bit-Bitmaps und alle GDI+-Funktionen klappen damit.
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

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

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

  Alt 18. Okt 2020, 21:24
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...
Angehängte Grafiken
Dateityp: jpg GDI.jpg (140,3 KB, 32x aufgerufen)
  Mit Zitat antworten Zitat
striderx

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

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

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

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

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
 
#6

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.560 Beiträge
 
Delphi 12 Athens
 
#7

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
Benutzerbild von Harry Stahl
Harry Stahl

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

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

  Alt 18. Okt 2020, 22:54
[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
  Mit Zitat antworten Zitat
striderx

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

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

  Alt 19. Okt 2020, 06:55
[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.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.378 Beiträge
 
Delphi 12 Athens
 
#10

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

  Alt 19. Okt 2020, 18:04
Umwandeln in 32 Bit und dann damit arbeiten macht den Code natürlich einfacher. (kein Align und Dergleichen)
Und das Kopieren der Pixel düfte in 32 Bit auch schneller sein. (kopieren ganzer und vor allem ausgerichteter Integer).
Wenn man es am Ende 32 Bit lässt (erstpart das Rückumwandeln), dann müsste man mal sehn, ob das Umwandeln von 24->32 Bit das Zeitplus des optimierten/einfacherem Codes für 32 Bit nicht auffrisst.

Nja, du mußt für die Berechnungen halt immer den richtigen Zeilenanfang benutzen.
* man könnte ein Array mit den Anfängen aufbauen, jeweils aus .Scanline[]
* oder du nimmst die letzte Zeile und mußt aber für die Zeilenbreite den ausgerichteten/aufgerundeten Wert benutzen

Delphi-Quellcode:
//LineWidth := RoundUp(LineWidth / 4) * 4;
//LineWidth := Trunc(/LineWidth + 3) / 4) * 4;
LineWidth := (LineWidth + 3) and not 3;
Das ScanLine[] in der Schleife braucht es auch nicht, denn Quell- und Zielpixel lassen sich gleichermaßen direkt von der letzten Zeile aus berechnen.
Pos = (X * LineWidthInByte) + (Y * PixelSizeInByte)

Ein INC mit den typisierten Zeigern ist nicht so praktisch, wenn man da das Align einbeziehen muß (bei 24 Bit),
aber über einen Cast nach PByte ließe sich das Problem lösen.
Delphi-Quellcode:
Inc(PByte(Sourc), PixelSizeInByte);
Inc(PByte(Dest), LineWidthInByte);
Delphi-Quellcode:
// für 24 Bit
Last := Scanline[Height - 1];
for Y := Height - 1 downto 0 do begin
  Src := Last - (Y * (Width * 3) + 3) and not 3; // oder Src := Last; vor die Y-Schleife und nach der X-Schleife ein Inc(PByte(Src), Die0bis3AlignBytes); bzw. Src auf den nächsten Integer aufrunden
  Dst := Last + Y * 3;
  for X := Width - 1 downto 0 do begin
    Dst^ := Src^;
    Inc(PByte(Src), 3);
    Dec(PByte(Dst), Width * 3); // bzw. die Pointer als Byte-Typ mit Pointerarithmetik und dafür der Cast beim Kopieren -> PRGBTripple(Dst)^ := PRGBTripple(Src)^;
  end;
end;

// für 32 Bit (das Auskommentierte für Byte-Typen)
Last := Scanline[Height - 1];
for Y := Height - 1 downto 0 do begin
  Src := Last - Y * Width {* 4}; // oder Src := Last; vor die Y-Schleife ... die Zeilen liegen ja alle sowieso direkt hintereinander
  Dst := Last + Y {* 4};
  for X := Width - 1 downto 0 do begin
    Dst^ := Src^;
    Inc(Src {, 4});
    Dec(Dst, Width {* 4});
  end;
end;
(falls ich mich nicht vertan hab)
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (19. Okt 2020 um 18:16 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


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 10:23 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