Einzelnen Beitrag anzeigen

Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#19

AW: Optimierung von Pixel

  Alt 8. Apr 2016, 09:09
Unter sehr leichtem Performaceverlust lässt sich Scanline auch ähnlich wie Pixels verwenden, wenn man sich eine kleine Helferprozedur bastelt.

Delphi-Quellcode:
procedure SetPixel(aBitmap: TBitmap; aX, aY: Integer; aColor: TColor);
var
  P: PRGBTriple;
begin
  if aBitmap.Pixelformat <> pf24Bit then
    raise Exception.Create('Bitmap hat falsches Pixelformat (nicht 24-Bit).');
  if (aX < 0) or (aX > aBitmap.Width) then
    raise Exception.Create('X-Koordinate liegt außerhalb des Bitmaps.');
  if (aY < 0) or (aY > aBitmap.Width) then
    raise Exception.Create('Y-Koordinate liegt außerhalb des Bitmaps.');
  P := aBitmap.Scanline[aY];
  Inc(P, aX);
  P^.R := GetRValue(aColor);
  P^.G := GetGValue(aColor);
  P^.B := GetBValue(aColor);
end;
Aufruf dann so:
Delphi-Quellcode:
    while BASS_ChannelIsActive(Channel) <> BASS_ACTIVE_STOPPED do begin
        BASS_ChannelGetData(Channel, Pointer(Buffer), BASS_DATA_FFT512);
        for i := 0 to BUFFER_SIZE - 1 do begin

            Value := SQRT(SQRT(Buffer[i]));
            H := 0 + Value / 1.5;
            L := Value;

            SetPixel(Image1.Picture.Bitmap, ColumnCounter, BUFFER_SIZE - i, HSLtoRGB(H, S, L));
        end;
        Inc(ColumnCounter);
        Progress := Trunc(100 * (BASS_ChannelGetPosition(Channel, BASS_POS_BYTE) / BASS_ChannelGetLength(Channel, BASS_POS_BYTE)));
        Form2.ProgressBar1.Position := Progress;
        Application.ProcessMessages;
    end;
Wenn man es direkt in seine Schleife baut, lässt sich halt das immer wieder erneute Abholen der Scanline vermeiden (zumindest innerhalb einer Zeile, und wenn man den Stride selber behandelt auch generell), und die Prüfungen fallen nur ein Mal an. Aber das hier düfrte dennoch etliche hundert Mal schneller als Pixels[] sein, bzw. kaum merklich langsamer als ohne die Krücken-Prozedur SetPixel().

Es kann sein, dass das Bild dann auf dem Kopf steht. Windows speichert Bitmaps nämlich auf dem Kopf, wenn ich mich nicht irre. Um das zu beheben müsste nur die Zeile P := aBitmap.Scanline[aY]; zu P := aBitmap.Scanline[aBitmap.Height-aY-1]; geändert werden.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium ( 8. Apr 2016 um 09:20 Uhr)
  Mit Zitat antworten Zitat