es ist einfach ineffektiv bei jedem aufruf Scanline erneut zu nutzen. Es reicht wenn man ein einziges mal scanline benutzt und sich den Rückgabewert merkt. Anschließend kann man von diesem Wert ausgehend auf die anderen Bytes zugreifen.
Ich meinte nicht immer eine Zeile komplett zu bearbeiten. Ich meinte wirklich nur einmal scanline zu nutzen.
Zur Veranschauligung hier mal meine
Unit die ich für schnelle Zugriffe nutze:
Delphi-Quellcode:
interface
uses
windows, graphics;
type
TBmpFast = class(TObject)
private
fFirstLine: Pointer;
fHeight : Cardinal;
fLineSize: Cardinal;
fWidth : Cardinal;
public
constructor Create;
property Height: Cardinal read fHeight;
function GetByte(X, Y: Word): PByte;
function GetRGBTriple(X, Y: Word): PRGBTriple;
function GetRGBQuad(X, Y: Word): PRGBQuad;
procedure Init(ABmp: TBitmap; ABitsPerPixel: Byte);
end;
implementation
constructor TBmpFast.Create;
begin
inherited Create;
fFirstLine := nil;
fLineSize := 0;
end;
function TBmpFast.GetByte(X, Y: Word): PByte;
begin
result := PByte(Cardinal(fFirstLine) - (fLineSize * Y) + X);
end;
function TBmpFast.GetRGBTriple(X, Y: Word): PRGBTriple;
begin
result := PRGBTriple(Cardinal(fFirstLine) - (fLineSize * Y) + (X * 3));
end;
function TBmpFast.GetRGBQuad(X, Y: Word): PRGBQuad;
begin
result := PRGBQuad(Cardinal(fFirstLine) - (fLineSize * Y) + (X * 4));
end;
procedure TBmpFast.Init(ABmp: TBitmap; ABitsPerPixel: Byte);
begin
fHeight := ABmp.Height;
fWidth := ABmp.Width;
fFirstLine := ABmp.ScanLine[0];
fLineSize := BytesPerScanline(fWidth, ABitsPerPixel, 32);
end;
end.
Ich rufe einfach die Init-methode auf un darin wird ein mal Scanline aufgerufen. Die zugriffe auf das Pixel X,Y erfolgen anschließend mit Berechnungen der Werte die bei Init ermittelt wurden. Also ohne erneutes Aufrufen von Scanline. Und somit mehr performance weil nicht jedes mal das ausgeführt wird was in der Scanlinefunktion eben so von statten geht.