Entwickler-Ecke

Multimedia / Grafik - Problem mit nem Pointer - ScanLines - pByte - ByteArray


RedBaron2k7 - Mo 16.04.07 23:10
Titel: Problem mit nem Pointer - ScanLines - pByte - ByteArray
Kann mir schnell mal jemand weiterhelfen?



Delphi-Quelltext
1:
type ByteArray = Array of Byte;                    




Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var
  temp_bitmap: TBitmap;  // temporary Bitmap
  temp_data: ByteArray;  // the "real" data
  p: pByte;  // data of one pixel
  w: Integer;  // width
  h: Integer;  // height
  i, i2, c: Integer; // iterations



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  p := temp_bitmap.Scanline[0];  // first scanline

  for i := 0 to 3*(w-1)*(h-1do begin  // rows
    temp_data[i] := p;
    Inc(Integer(p), 1);  // next pixel-color
  end;


Der Fehler liegt in der rot markierten Zeile ...
* p ist der byte-Pointer
* temp_data ist ein Byte-Array

Wie bekomm ich Daten die am Pointer liegen in das Array?

Thx 4 ur help :)


ConditionZero - Mo 16.04.07 23:11

Welche rote Zeile :?:


RedBaron2k7 - Mo 16.04.07 23:12

user profile iconConditionZero hat folgendes geschrieben:
Welche rote Zeile :?:


die da ^^

color ging ne ^^


Narses - Mo 16.04.07 23:12

Ganze schnelle Hilfe: Suche in: Delphi-Forum, Delphi-Library SCANLINES :lol:


BenBE - Mo 16.04.07 23:19

Nimm ein Type PByteArray = ^TByteArray; mit der Definition Type TByteArray = Array[0..] of Byte; und weise dieses mit P{: PByteArray} := BMP.ScanLine[0] zu. Index-Zugriff dann wie gewohnt, jedoch mit Dereferenzierung auf P^[i], um dem Zeiger Rechnung zu tragen.


RedBaron2k7 - Di 17.04.07 00:01

user profile iconBenBE hat folgendes geschrieben:
Nimm ein Type PByteArray = ^TByteArray; mit der Definition Type TByteArray = Array[0..] of Byte; und weise dieses mit P{: PByteArray} := BMP.ScanLine[0] zu. Index-Zugriff dann wie gewohnt, jedoch mit Dereferenzierung auf P^[i], um dem Zeiger Rechnung zu tragen.


Ich möche jedoch nureine Schleifverwenden, und mit dieser Byte-weise in mein Array kopieren .... das ganze steht ja schon .... nur irgendwas stimmt mit dem Pointer net ... also demwas ich oben markiert habe .... das muss doch auch so gehen...

wäre schön wenn sich das so lösen lässt ...


RedBaron2k7 - Di 17.04.07 00:03

weitere Frage gleich noch ....


Delphi-Quelltext
1:
Inc(Integer(p), 1);                    



brauch ich da das Integer() ???

Kenne mich mit Pointern noch nicht so gut aus ^^


BenBE - Di 17.04.07 00:13

Nein, das Integer brauchst Du nicht. Du solltest Dir aber bewusst sein, dass Inc(p); und Inc(p^); zwei völlig unterschiedliche Dinge sind ...

Zu deiner Schleifenvariable: Es hat einen guten Grund, warum ich Dir den Weg mit dem Array empfehle ... 1. Sauberer, 2. Intuitiver zu verwenden, 3. Gebräuchlicher...


RedBaron2k7 - Di 17.04.07 00:16

user profile iconBenBE hat folgendes geschrieben:
Nein, das Integer brauchst Du nicht. Du solltest Dir aber bewusst sein, dass Inc(p); und Inc(p^); zwei völlig unterschiedliche Dinge sind ...

Zu deiner Schleifenvariable: Es hat einen guten Grund, warum ich Dir den Weg mit dem Array empfehle ... 1. Sauberer, 2. Intuitiver zu verwenden, 3. Gebräuchlicher...


jop ... inc(p) geht zur nächsten speicheraddresse
und inc(p^) erhöht den wert an der speicheraddresse soweit ich weiss ???

na, ich überdenke das ganze nochmal ... wie sieht es mit den TRGBQuads oder wie die heißen aus der windows.pas aus?


BenBE - Di 17.04.07 00:29

Kann man alternativ zu Byte verwenden. Beachte dann aber, für welches Pixel-Format Du das verwendest ...


RedBaron2k7 - Di 17.04.07 01:41

user profile iconBenBE hat folgendes geschrieben:
Kann man alternativ zu Byte verwenden. Beachte dann aber, für welches Pixel-Format Du das verwendest ...


So... habe das ganze nun in das "Format" mit den ByteArrays gebracht ...

Jedoch hängts nun an dieser Zeile ...
Wie komme ich in die nächste ScanLine? Ohne dabei den Befehl ScanLine() selbst aufzurufen...

Theoretisch ja Addresse von "p" + Größe von einer Zeile (ScanLine)


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
  p := temp_bitmap.Scanline[0];  // first scanline

  {read each pixel and color one-by-one}
  for i := 0 to (h - 1do begin  // rows
    SetLength(temp_data[i], 3*w);
    for j := 0 to (3*w - 1do begin
      temp_data[i][j] := p^[j];
    end;

   Inc(p, 1);
  end;


BenBE - Di 17.04.07 01:44

Genau eben nicht. Du musst es mit Scanline machen, weil Bitmaps intern Bottom-Up gespeichert sind ... Wie die Adressberechnung genau funktioniert, steht in den VCL-Units. Grob gesagt aber: Rundung auf 4-Byte-Adresse nach Ende der vorigen Zeile.


RedBaron2k7 - Di 17.04.07 01:58

Zitat:
Na dann bringt mir das so aber garnix :(

Weil ich ja ScanLine() nicht ständig aufrufen willl .... zeitkritisch ...

Das frisst nen Haufen Performance :(


Ich nehms zurück, werde wohl den Fehler woanders haben .. habe nun jedenfalls auch ne Methode, mit der ich das mehrfache Aufrufen von ScanLine() umgehen kann :)


RedBaron2k7 - Di 17.04.07 03:09

So ... hier nun meine Lösung ...

Werde das Thema als "gelöst markieren"^^


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
  p := temp_bitmap.Scanline[0];  // first scanline

  { bitmaps are saved in reversed order -> "-"
    ds = difference between two ScanLines }

  ds := Integer(temp_bitmap.Scanline[1]) - Integer(p);

  {read each pixel and color one-by-one}
  for i := 0 to (h - 1do begin  // rows - loop
    SetLength(temp_data[i], 3*w);  // reserve memory for the pixels

    for j := 0 to (3*w - 1do begin  // pixel-data - loop
      temp_data[i][j] := p^[j];  // getdata fom memory and store it temporarly
    end;

    Inc(Integer(p), ds);  // next ScanLine
  end;