Dein Code ist viel zu kompliziert und dadurch auch langsam.
So könntest du es für 24Bit tun. Und für die anderen Formate natürlich ähnlich.
Delphi-Quellcode:
procedure CreateSpecialImage(const InBmp, OutBmp: TBitmap; Threshold: Byte);
var
OutPixel: PRgbTriple;
height, width, x, y: Integer;
begin
OutBmp.Assign(InBmp);
Height := OutBmp.Height;
Width := OutBmp.Width;
for y := 0 to Height - 1 do
begin
OutPixel := OutBmp.ScanLine[y];
for x := 0 to Width - 1 do
begin
if OutPixel^.Blue > Threshold then OutPixel^.Blue := Threshold;
if OutPixel^.Red > Threshold then OutPixel^.Red := Threshold;
if OutPixel^.Green > Threshold then OutPixel^.Green := Threshold;
inc(OutPixel);
end;
end;
end;
Von wegen langsam:
Dein Code ruft TBitmap.Scanline Width*Height-mal auf. Jeder dieser Aufrufe ist extrem lahm, wenn auch schon wesentlich schneller als der Zugriff auf TBitmap.Canvas.Pixel[x,y]. Genau das war der Punkt in meinem Blog-Post, auf den Bernhard im ersten Post verwiesen hat. Und da er jedes Pixel sowieso nochmal anpasst, kann er auch gleich die erste Bitmap pixelweise lesen und die zweite schreiben, das spart dann auch noch das TBitmap.Assign.
Edit: Und Himitsu hat recht: Da die Grenze für alle Farben dieselbe ist, kann man die
RGB-Bytes auch einfach mittels einer Schleife von 3*Width byteweise abarbeiten statt ein PRgbTriple zu verwenden. Ob das von der Performance her nochmal einen großen Unterschied macht, weiß ich aber nicht. Die Vermeidung der Scanline-Aufrufe bringt deutlich mehr.