Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Scanline vs Pixels (https://www.delphipraxis.net/59127-scanline-vs-pixels.html)

SleepyMaster 17. Dez 2005 19:56


Scanline vs Pixels
 
Hi ihrs...

warum erzielen die unteren beiden Zeilen nicht das selbe Ergebniss?

Delphi-Quellcode:
type
  TScanLine = array[0..0] of TColor;
  PScanLine = ^TScanLine;

...

  Color := PScanLine(Image1.Picture.Bitmap.Scanline[x])[y];
  Color := Image1.Canvas.Pixels[y, x];

...
Und wie kann ich es hinbekommen, dass ich mit Scanlines das selbe bewirke wie mit Pixels?

Vielen Dank
SleepyMaster

xaromz 17. Dez 2005 20:13

Re: Scanline vs Pixels
 
Hallo,

weil Du bei der Zeile
Delphi-Quellcode:
Color := PScanLine(Image1.Picture.Bitmap.Scanline[x])[y];
x und y tauschen musst. Y ist die Zeile, X die Spalte.

Gruß
xaromz

Der_Unwissende 17. Dez 2005 20:17

Re: Scanline vs Pixels
 
Ausserdem ist dein Code extrem unsicher, du solltest darauf achten welches Pixelformat dein Bitmap hat.

Gruß Der Unwissende

Airblader 17. Dez 2005 21:14

Re: Scanline vs Pixels
 
@xaromz

Schau mal genau hin - er hat beim Pixels vertauscht. Sollte also nicht das Problem sein ;)

air

xaromz 17. Dez 2005 21:19

Re: Scanline vs Pixels
 
Hallo,
Zitat:

Zitat von Airblader
@xaromz

Schau mal genau hin - er hat beim Pixels vertauscht. Sollte also nicht das Problem sein ;)

air

tatsächlich. Dann kann man meinen Vorschlag wohl vergessen :stupid: .

Gruß
xaromz

alzaimar 17. Dez 2005 21:29

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:

Muetze1 17. Dez 2005 22:49

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.

alzaimar 18. Dez 2005 08:36

Re: Scanline vs Pixels
 
Zitat:

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.

Ich hatte bei meiner Anmerkung die Deklaration in Sleepymasters-Code ignoriert...

Der_Unwissende 18. Dez 2005 11:15

Re: Scanline vs Pixels
 
Zitat:

Zitat von alzaimar
Zitat:

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]

SleepyMaster 18. Dez 2005 13:57

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 03:02 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz