Thema: Delphi Scanline vs Pixels

Einzelnen Beitrag anzeigen

Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#9

Re: Scanline vs Pixels

  Alt 18. Dez 2005, 11:15
Zitat von alzaimar:
Zitat von Muetze1:
ScanLine ist kein Byte Array in dem Sinne - was wäre es denn bei pf1bit? Ein Bit-Array?
Ja, etwa nicht? Scanline ermöglicht den Zugriff auf die rohen Bilddaten, und das wäre doch bei pf1bit ein Bit-Array.
Hast schon recht, was du eigentlich hast ist ein Bit-Array, aber bekommen tust du weiterhin nur den Zeiger auf ein Byte-Array. Wie die Daten in diesem Byte-Array abgelegt werden (z.B. jedes Bit entspricht einem Pixel oder 4 Byte entsprechen einem Pixel) hängt dann aber komplett von dem Pixelformat der DIB ab.

Um mittels ScanLine das gleiche zu tun wie mittels Pixels müsste man einfach nur ein BGR Wert an die ScanLine übergeben. Also anders gesagt, der Rot und Grünanteil von einem TColor Wert muss getauscht werden.
Dann ist alles ganz einfach :

Delphi-Quellcode:
function ColorToBGR(b : Byte; g : Byte; r : Byte) : Integer; overload;
begin
  result := b + (g shl 8) + (r shl 16);
end;

function ColorToBGR(Color : TColor) : Integer; overload;
begin
 result := (Color and $FF000000) + ((Color and $000000FF) shl 16) + (Color and $0000FF00) + ((Color and $FF0000) shr 16);
end;

procedure setColor(const Bitmap : TBitmap; const X, Y : Integer; const Color : TColor);
var p : PIntegerArray;
begin
  if assigned(Bitmap) then
    begin
      Bitmap.PixelFormat := pf32Bit;
      p := Bitmap.ScanLine[y];
      p[x] := ColorToBGR(Color);
    end; // if assigned(Bitmap)
end;
Aber effizient ist Scanline natürlich erst so richtig, wenn man mehr als einen Pixelwert verändern möchte. Letztlich bedeutet jeder Funktionsaufruf ein wenig Overhead und wenn du für jedes Pixel einen Zeiger auf die Zeile bekommst, brauchst du den ja auch nur einmal um gleich die ganze Zeile abzuarbeiten.
Man kann natürlich auch mit einer Bitmap in anderen PixelFormaten arbeiten, aber 32 Bit bietet sich sicherlich auf jedem 32 Bit Rechner an, auf dem der Speicher für eine Zeile nicht zu knapp ist.

[Edit]
Ups, falsche Frage beantwortet, muss natürlich umgekehrt aussehen:

Delphi-Quellcode:

function BGRToColor(const BGR : Integer) : TColor;
begin
  result := (BGR and $FF000000) + ((BGR and $00FF0000) shl 16) + (BGR and $0000FF00) + ((BGR and $00FF0000) shr 16);
end;

function getColor(const Bitmap : TBitmap; const X, Y : Integer) : TColor;
var p : PIntegerArray;
begin
  if assigned(Bitmap) then
    begin
      Bitmap.PixelFormat := pf32Bit;
      p := Bitmap.ScanLine[y];
      result := BGRToColor(p[x]);
    end; // if assigned(Bitmap)
end;
So stimmts dann hoffentlich.
[/Edit]
  Mit Zitat antworten Zitat