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;