AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?
Thema durchsuchen
Ansicht
Themen-Optionen

Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

Ein Thema von Harry Stahl · begonnen am 21. Feb 2016 · letzter Beitrag vom 28. Feb 2016
Antwort Antwort
Seite 1 von 7  1 23     Letzte »    
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.533 Beiträge
 
Delphi 11 Alexandria
 
#1

Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 21. Feb 2016, 19:04
Derzeit verwende ich folgende Methode, um ein 32-bit-Bitmap auf Vorhandensein eines (Teil-) Transparenten Pixels zu prüfen:

Delphi-Quellcode:
function HasTransparentRGBAValues (const bm:TBitmap): Boolean;
var
  x, z: Integer; RGBA: pRGBALine;
begin
  Result := FALSE;
  RGBA := bm.Scanline[bm.Height-1];
  z := bm.Width * bm.Height;

  for x := 0 to z-1 do begin
    if RGBA^[x].rgbReserved <> 255 then begin
      EXIT (TRUE);
    end;
  end;
end;
Bei einem Nicht transparentem Bild in den Ausmaßen 4244x2819 Pixel benötigt die Routine hier auf meinem Rechner ca. 80 MS um das ganze Bitmap zu prüfen, was ziemlich viel Zeit ist.

Kennt jemand da evtl. eine noch schnellere Methode als die oben dargestellte?
  Mit Zitat antworten Zitat
Delphi-Laie

Registriert seit: 25. Nov 2005
1.474 Beiträge
 
Delphi 10.1 Berlin Starter
 
#2

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 21. Feb 2016, 19:08
Delphi-Quellcode:
function HasTransparentRGBAValues (const bm:TBitmap): Boolean;
var
  x, z: Integer; RGBA: pRGBALine;
begin
  Result := FALSE;
  RGBA := bm.Scanline[bm.Height-1];
  z := bm.Width * bm.Height;

  for x := 0 to z-1 do begin
    if RGBA^[x].rgbReserved <> 255 then begin
      EXIT (TRUE);
    end;
  end;
end;
Warum hat die Funktion nie die Möglichkeit, true zurückzuliefern?

Edit: OK, das wird wohl im Exitparameter realisiert - diese Möglichkeit war mir neu.
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.159 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 21. Feb 2016, 19:50
Parallelisieren?
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.533 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 21. Feb 2016, 20:36
Bin mir da nicht so sicher, wegen des Overheads. Hatte ich zwar schon mal gemacht, allerdings zeigt mir AQtime seltsame Messwerte an (0,3 MS, was nicht sein kann) und bei einem Extra-Test-Projekt schwanken die einzelnen Testergebnisse zwischen 28 und 56 MS:

Delphi-Quellcode:
type
  TRGB32 = packed record
    B, G, R, A: Byte;
  end;

  TRGB32Array = packed array[0..MaxInt div SizeOf(TRGB32)-1] of TRGB32;
  PRGB32Array = ^TRGB32Array;

function HasTransparentRGBAValuesx (const bm:TBitmap): Boolean;
var
  LineLen: Integer; found: boolean;
  FirstLine : PRGB32Array;
begin
  Found := false;
  if bm.Width = 0 then exit;

  FirstLine := bm.ScanLine[0];
  LineLen := - bm.width;

  TParallel.For (0, bm.Height-1, procedure (y:Integer; S: TParallel.TLoopState)
  var
    x, p: Integer;
  begin
    if not s.ShouldExit then begin
      P := y*LineLen;
      for x := 0 to bm.Width-1 do begin
        if FirstLine[P+x].A <> 255 then begin
          found := true;
          s.Break;
          break;
        end;
      end;
    end;
  end);

  Result := found;
end;
Insofern wäre mir hier eine Variante ohne Parallelisierung mit eindeutig besseren Ergebnissen lieber
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#5

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 21. Feb 2016, 20:38
Bitmap komplett in den Speicher laden, damit man keine Festplattenzugriffe hat und dann mit zwei Threads von vorne und hinten prüfen?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 21. Feb 2016, 21:00
Ich hätte schon Ideen, aber dafür wäre ein Beispielbild sehr gut. Ohne Photoshop kenne ich auf Anhieb kein Tool, mit dem ich einer Bitmap einen Alphakanal hinzufügen könnte.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#7

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 21. Feb 2016, 21:56
Das TParallel.For über die 2819 Zeilen verursacht wahrscheinlich mehr Overhead als die Parallelisierung wettmachen kann. Wenn das ganze Bild ca. 80 ms braucht, dann sind das pro Zeile (also pro Iteration) ca. 0,03 ms. Das ist ein ganz schlechtes Verhältnis. Besser auf deutlich weniger Durchläufe beschränken und jede Iteration über ca. 100-500 Zeilen laufen lassen. Das sind dann pro Task ca. 3-15ms. Mit genügend freien Kernen sollte das merkbar sein.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.533 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 21. Feb 2016, 22:15
Ich hätte schon Ideen, aber dafür wäre ein Beispielbild sehr gut. Ohne Photoshop kenne ich auf Anhieb kein Tool, mit dem ich einer Bitmap einen Alphakanal hinzufügen könnte.
Na, sowas sollte ja wohl jedes Grafikbearbeitungsprogramm drauf haben (in meinem Programm - PixPower - wählt man dazu einfach im Dropdown-Schalter "Farbe" unter Menü "Farbtiefe" 32 Bit, siehe anliegenden Screenshot).

Photoshop braucht man dafür wirklich nicht.

Aber wie auch immer, habe mal die Demo so verändert, dass die Grafik zur Laufzeit erzeugt wird (will hier keine 45 MB-Grafikdatei beifügen).

Mit den Schaltern Standard und Parallel kann man die Geschwindigkeit testen, wenn keine Transparenz vorhanden ist. Mit dem Schalter "SetTransparency" macht man eine Zeile transparent und kann dann die Routinen noch mal ausführen.

Projekt anliegend.
Miniaturansicht angehängter Grafiken
32bit.jpg  
Angehängte Dateien
Dateityp: zip transparent.zip (57,7 KB, 16x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.533 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 21. Feb 2016, 22:29
Das TParallel.For über die 2819 Zeilen verursacht wahrscheinlich mehr Overhead als die Parallelisierung wettmachen kann. Wenn das ganze Bild ca. 80 ms braucht, dann sind das pro Zeile (also pro Iteration) ca. 0,03 ms. Das ist ein ganz schlechtes Verhältnis. Besser auf deutlich weniger Durchläufe beschränken und jede Iteration über ca. 100-500 Zeilen laufen lassen. Das sind dann pro Task ca. 3-15ms. Mit genügend freien Kernen sollte das merkbar sein.
Ja, wäre eine mögliche Verbesserung. Doch damit steigt die Komplexität wieder an und es wird so ein unschönes unleserliches Ungetüm draus. Und ob es schneller ist?

Insofern wäre mir eine Standard-Lösung lieber, z.B. per ASM.

Kenne mich mit Assembler aber leider nicht so gut aus.
Aber hier muss ja letztlich nur über einen zusammenhängenden Speicherbereich, jeweils in Abständen von 4 Byte geprüft werden, ob das Byte dort <> 255 ist.

Nichts anderes macht ja im Prinzip meine Standard-Methode. Aber gibt es da nicht so einen Super ASM-Befehl, der das in einem Rutsch ohne Iteration erledigen kann?
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#10

AW: Prüfung eines Bitmaps auf Transparenz (gehts noch schneller)?

  Alt 21. Feb 2016, 22:35
Das mit der gröberen Aufteilung sollte man probieren.
Eventuell könnte man mit den Vektoreinheiten (SSE) noch was heraushole. Das wird dann aber haariger (kA. wie weit Delphi von alleine vektorisiert).

Edit:
Doch damit steigt die Komplexität wieder an und es wird so ein unschönes unleserliches Ungetüm draus. Und ob es schneller ist?[...] Insofern wäre mir eine Standard-Lösung lieber, z.B. per ASM.
Frei nach Herb Sutter "Free lunch is over". Parallelisieren ist die Standard-Lösung.
Und dein Problem ist wirklich noch einfach zu parallelisieren

Geändert von BUG (21. Feb 2016 um 22:56 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 7  1 23     Letzte »    


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 14:57 Uhr.
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