Einzelnen Beitrag anzeigen

Amateurprofi

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

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

  Alt 25. Feb 2016, 20:15
Zu #54 von Memnarch:
Ich hätte da noch eine super superschnelle Funktion anzubieten, sehr kurz, unkompliziert und übersichtlich:

Delphi-Quellcode:
function HasTransparentRGBAValues(const bm:TBitmap): Boolean;
begin
   Result:=True;
end;
@Memnarch:
Ist natürlich nicht ernst gemeint, deshalb bitte nicht böse sein.
Aber genau das liefert Deine in #54 gepostete Funktion.
Ich habe mal versucht, zu verstehen was Deine Funktion genau macht und habe eine kommentierte Version erstellt.
Hoffentlich hab ich mich da nicht vertan.
Delphi-Quellcode:
function HasTransparentRGBAValues(bmp:TBitmap): Boolean;
type
   TRGBA = packed record
     B, G, R, A: Byte;
   end;
   PRGBA = ^TRGBA;
   TRGBA4 = array[0..3] of TRGBA;
   PRGBA4 = ^TRGBA4;
   TScanLine = array[0..100000] of TRGBA;
   PScanLine = ^TScanLine;
var
   z: Integer;
   RGBA: PScanLine;
   LPixels, LLastPixels: PRGBA4;
   LPixel: PRGBA;
   i: Integer;
begin
   RGBA := bmp.Scanline[bmp.Height-1]; // Zeigt auf erstes Pixel der Bitmap
   z := bmp.Width * bmp.Height; // Anzahl Pixel
   LPixels := @RGBA[0]; // Adresse des ersten Pixels
   LLastPixels := @RGBA[z div 4 * 4]; // Zeigt hinter das letzte durch 4 teilbare Pixel
   while (LPixels <> LLastPixels) and ((LPixels[0].A and LPixels[1].A and LPixels[2].A and LPixels[3].A) = 255) do
     Inc(LPixels);
   // LPixels zeigt jetzt
   // 1) entweder auf das erste von 4 Pixeln, von denen mindestens eins transparent ist.
   // 2) oder, wenn Z nicht durch 4 teilbar ist, hinter das letzte durch 4 teilbare Pixel.
   // 3) oder, wenn Z durch 4 teilbar ist, hinter das letzte Pixel der Bitmap.
   Result := ((LPixels[0].A and LPixels[1].A and LPixels[2].A and LPixels[3].A) <> 255);
   // Die obige Ermittlung des Resultats ist für die Fälle 2 und 3 fehlerhaft
   // weil hier auf Speicherbereiche zugegriffen wird, die nicht mehr zur
   // Bitmap gehören.
   // Im Fall (2), weil ab LPixels maximal 3 Pixel folgen
   // Im Fall (3), weil LPixels bereits außerhalb der Bitmap liegt
   // Wenn in diesem Bereich mit undefiniertem Inhalt NICHT zufällig das 4te und
   // 8te und 12te und 16te Byte = 255 sind (was in der Regel nicht vorkommt),
   // wird als ergebnis TRUE geliefert.
   if not Result then
   begin
     Inc(LPixels);
     LPixel := PRGBA(LPixels);
     for i := 0 to z mod 4 - 1 do
     begin
       if LPixel.A < 255 then
         Exit(True);
       Inc(LPixel);
     end;
   end;
end;
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat