![]() |
Scanline vs Pixels
Hi ihrs...
warum erzielen die unteren beiden Zeilen nicht das selbe Ergebniss?
Delphi-Quellcode:
Und wie kann ich es hinbekommen, dass ich mit Scanlines das selbe bewirke wie mit Pixels?
type
TScanLine = array[0..0] of TColor; PScanLine = ^TScanLine; ... Color := PScanLine(Image1.Picture.Bitmap.Scanline[x])[y]; Color := Image1.Canvas.Pixels[y, x]; ... Vielen Dank SleepyMaster |
Re: Scanline vs Pixels
Hallo,
weil Du bei der Zeile
Delphi-Quellcode:
x und y tauschen musst. Y ist die Zeile, X die Spalte.
Color := PScanLine(Image1.Picture.Bitmap.Scanline[x])[y];
Gruß xaromz |
Re: Scanline vs Pixels
Ausserdem ist dein Code extrem unsicher, du solltest darauf achten welches Pixelformat dein Bitmap hat.
Gruß Der Unwissende |
Re: Scanline vs Pixels
@xaromz
Schau mal genau hin - er hat beim Pixels vertauscht. Sollte also nicht das Problem sein ;) air |
Re: Scanline vs Pixels
Hallo,
Zitat:
Gruß xaromz |
Re: Scanline vs Pixels
Moment mal, Leute: Scanline ist doch ein Byte-Array, wie kann da denn ein 32bit Color-Wert drin sein, oder irre ich mich?
Bei einer Farbtiefe von 24 bit kann man über Scanline nacheinander die R G und B Werte (Reihefolge eventuell anders) abrufen. Is aber auch schon spät, also :mrgreen: |
Re: Scanline vs Pixels
ScanLine ist kein Byte Array in dem Sinne - was wäre es denn bei pf1bit? Ein Bit-Array?
Grundsätzlich spiegelt sich der Aufbau der Farben abhängig vom PixelFormat wieder und dabei ist es bei pf24Bit auch ein Array of TRGBTriple und bei pf32Bit vom Typ TRGBQuad und somit nicht unbedingt Array Of byte. Die "Strukturmaske" kann man ja beliebig definieren. Und bei pf32bit bekommt man ein TRGBQuad mit Red, Green, Blue und Reserved - was einem 32 Bit Wert zusammengefasst entspricht. Ich bin mir aber nun nicht auf Anhieb sicher, wie es sich mit dem Rot- und Grünanteil aussieht, ob der nicht vertauscht war bei TColor oder beim TRGBQuad bei pf32bit. Wenn nicht, dann ist es ein TColor Wert - wenn man das eine Byte vernachlässigt. Dieses Byte ist aber wiederrum für die VCL wichtig und daher sollte man am besten so oder so die Funktion (C/C++: Makro) RGB() nutzen, um einen TColor Wert zu erstellen. Dann ist auch die Frage mit dem vertauschten Rot- und Grünanteilen hinfällig. |
Re: Scanline vs Pixels
Zitat:
Ich hatte bei meiner Anmerkung die Deklaration in Sleepymasters-Code ignoriert... |
Re: Scanline vs Pixels
Zitat:
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:
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.
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; 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:
So stimmts dann hoffentlich.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; [/Edit] |
Re: Scanline vs Pixels
Vielen Dank... nur hattest du in BGRToColor einen kleinen Dreher drin, der das Bild ein bisschen gelbstichig macht :zwinker:
Delphi-Quellcode:
function BGRToColor(const BGR : Integer) : TColor;
begin result := (BGR and $FF000000) + ((BGR and $000000FF) shl 16) + (BGR and $0000FF00) + ((BGR and $00FF0000) shr 16); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz