Einzelnen Beitrag anzeigen

Benutzerbild von dummzeuch
dummzeuch
Online

Registriert seit: 11. Aug 2012
Ort: Essen
1.598 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#9

AW: weniger Scanline aufrufe ... Graustufenbild

  Alt 11. Feb 2024, 16:21
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.
Thomas Mueller

Geändert von dummzeuch (11. Feb 2024 um 16:27 Uhr)
  Mit Zitat antworten Zitat