Einzelnen Beitrag anzeigen

Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
721 Beiträge
 
Delphi 11 Alexandria
 
#20

AW: weniger Scanline aufrufe ... Graustufenbild

  Alt 12. Feb 2024, 20:38
Hallo Thomas dein in #15 gezeigter 24Bit Bitmap Code auf #1 angewendet läuft bei mir nun in 1820ms (1000 Mal 1000x1000Pixel) durch.

Delphi-Quellcode:
procedure DZeuch(_SrcBmp, _DstBmp: TBitmap; Threshold: Byte);
const
  BytesPerPixel = 3;
var
  x: Integer;
  y: Integer;
  w: Integer;
  h: Integer;
  SrcLine: PByte;
  DstLine: PByte;
  SrcPixel: PByte;
  DstPixel: PByte;
  BytesPerLine: Integer;
begin
  _SrcBmp.PixelFormat := pf24bit;
  _DstBmp.PixelFormat := pf24bit;
  w := _SrcBmp.Width;
  h := _SrcBmp.Height;
  _DstBmp.SetSize( w, h);

  if h = 0 then
    Exit; //==>

  BytesPerLine := ((w * 8 * BytesPerPixel + 31) and not 31) div 8;

  SrcLine := _SrcBmp.ScanLine[0];
  DstLine := _DstBmp.ScanLine[0];
  for y := 0 to h - 1 do begin
    SrcPixel := SrcLine;
    DstPixel := DstLine;
    for x := 0 to w - 1 do begin
      PdzRgbTriple(DstPixel)^ := PdzRgbTriple(SrcPixel)^;
      if PdzRgbTriple(DstPixel)^.Blue > Threshold then PdzRgbTriple(DstPixel)^.Blue := Threshold;
      if PdzRgbTriple(DstPixel)^.Green > Threshold then PdzRgbTriple(DstPixel)^.Green:= Threshold;
      if PdzRgbTriple(DstPixel)^.Red > Threshold then PdzRgbTriple(DstPixel)^.Red:= Threshold;
      Inc(SrcPixel, BytesPerPixel);
      Inc(DstPixel, BytesPerPixel);
    end;
    Dec(SrcLine, BytesPerLine);
    Dec(DstLine, BytesPerLine);
  end;
end;
Du hast Recht. Assign macht (für den vorliegenden Fall) viele unnötige Dinge. Wenn ich darauf verzichte (man gewinnt ca. 0.5ms), dann läuft mein Code in 810ms:

Delphi-Quellcode:
procedure CreateSpecialImage3(const InBmp, OutBmp : TBitmap; Threshold: Byte);
var // InBmp, OutBmp pf24Bit
  SrcScanline, DstScanline : Pointer;
  OutPixel: PRGBTriple;
  deltascan : NativeInt;
  height, width, x, y: Integer;
begin
  Height := InBmp.Height;
  Width := InBmp.Width;
  OutBmp.PixelFormat := pf24Bit;
  OutBmp.SetSize(width,height);
  if height = 0 then exit;

  DstScanline := OutBmp.ScanLine[height-1];
  SrcScanline := InBmp.ScanLine[height-1];

  if height > 1 then
  deltascan := NativeInt(OutBmp.ScanLine[height-2]) - NativeInt(DstScanline) else deltascan := 0;

  Move( SrcScanline^, DstScanline^, deltascan*height);

  for y := Height - 1 downto 0 do
  begin
    OutPixel := DstScanline;
    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;
     inc(PByte(DstScanline), deltascan);
  end;
end;
Natürlich gibt's wie erwähnt wurde noch Assembler und breite Register (habe ich auch schon mal woanders genutzt - mein Rechner wurde dann wegen der Hitze runter getaktet...), Grpahics32, GDI+ (Clone)... - aber 1000 Bilder zu 1000*1000*24 Bit Bitmaps mit den "doofen" alten Grafikfunktionen in 810ms ist schon recht schnell.
Michael Gasser

Geändert von Michael II (13. Feb 2024 um 15:24 Uhr)
  Mit Zitat antworten Zitat