Laden...

Pointer verwechsel ich ständig

Erstellt von digi333 vor 16 Jahren Letzter Beitrag vor 16 Jahren 2.073 Views
D
digi333 Themenstarter:in
290 Beiträge seit 2006
vor 16 Jahren
Pointer verwechsel ich ständig

Ich verwechsel immer bei Pointer zwei Sachen... Mit


byte* Pix = (byte*)(void*)RGB;
Pix += 3;

geht man einen Bildpunkt weiter und mit


Pix[0]

wählt man den RGB-Wert. Richtig?

Wie müßte dann der Code aussehen um aus Pixelzeile 27 alle R-Werte zu mitteln, wenn ein Bild 300x100 Pixel groß ist?

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo digi333,

wenn es nicht um das allerletzte Quäntchen Performance geht, solltest du nicht mit Pointern arbeiten, sondern bmpdNew.Scan0 mit Marshal.Copy in ein byte-Array kopieren (und ggf. später wieder zurück).

Pro Zeile des Bildes sind dann bei einem 24bit Bild 3 * Width Bytes aufgerundet auf volle 4 Bytes in dem Array enthalten. Jedes Byte steht für ein Subpixel, drei Bytes bilden ein Pixel. Wenn aufgerundet wurde, stehen am Ende einer Zeile bis zu drei Füllbytes, deren Inhalt keine Bedeutung hat. Anschließe stehen die (Sub-)Pixelwerte der folgenden Bildzeile.

Bei 3 * 300 = 900 muss nicht aufgerundet werden. Eine Bildzeile ist 900 Bytes lang. Entsprechend beginnt die 27 Zeile bei Offset (27 - 1) * 900. An diesem Offset ist der R-Wert des ersten Pixels der Zeile. Alle weiteren R Werte stehen jeweils 3 Bytes weiter rechts.

herbivore

D
digi333 Themenstarter:in
290 Beiträge seit 2006
vor 16 Jahren

Performance spielt leider ne große Rolle... Sagen wir mal ich müßte weiter mit Pointer arbeiten (da der Codec mir Pointer liefert)... wie kann ich weiter arbeiten. Wie wär das Problem mit den R-Werten in Pointerschreibweise???

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo digi333,

das Prinzip ist - ob Array oder Pointer - das gleiche, also so wie ich beschrieben habe.

herbivore

D
digi333 Themenstarter:in
290 Beiträge seit 2006
vor 16 Jahren

for (int y = 0; y <= ((myframe.Height / 8) - 1) / 3; y++)
{
     if (...)
     for (int y1 = y*16; y1 < 16; y1++)
     {
           for (int x1 = 0; x1 < frameWidth; x1++)
           {
                  RTemp += Pix[(y1*3) + (x1*3)];
                  Pix += 3;                      
            }
     }
     Ausgabe von RTemp;
}

Also in dem oberen Code habe ich das Problem, dass alle Werte von RTemp gleich sind... sollten sie aber nicht. Läßt natürlich darauf schließen, dass nicht an die richtige Stelle im Bild springe, sondern immer die gleichen Zeilen ablaufe.

D
78 Beiträge seit 2007
vor 16 Jahren

Wenn du mit einem Bytepointer auf deine Farbdaten zeigst...


byte* Pix = (byte*)(void*)RGB;

...kannst du per...


Pix += 3;

...zum nächsten Farbwert (R8G8B8 => 3 Byte / Pixel) springen, und per...


byte r = *pix;
byte g = *(pix+1);
byte b = *(pix+2);

...oder per []-Operator...


byte r = Pix[ 0 ];
byte g = Pix[ 1 ];
byte b = Pix[ 2 ];

...auf die aktuellen drei Farbkomponenten zugreifen (voraussetzung ist das die Farbkanäle wirklich in der Form R G B angeordnet sind).

Da du ein eindimensionalen Array hast kannst du über Pix[ 273003 ] zum ersten Farbwert der Scanline 27 springen (=> Pixel(x,y) = Pix[y*width+x]). Dann kannst du per Schleife durch die Farbwerte iterieren und jeweils die erste Komponente auslesen:

Ungetestet:


byte* p = &Pix[ 27*300*3 ];
float sum = 0;
 
for ( int i = 0; i < 100; i++, p += 3 )
{
    sum += *p;    
}

sum *= 0.01f; // p1+p2+p3+...+p100 / 100

D
digi333 Themenstarter:in
290 Beiträge seit 2006
vor 16 Jahren

Das is ja mal einer sehr ausführliche Hilfe. In deinen Erklärungen sind genau die zwei Hauptfragen drinne, die ich immer habe... ist Pix[3] das gleiche wie Pix[0] vom zweiten Pixel? und wie ist unterschied zwischen []-Operator und *Wert?

Trotzdem mach ich in meinem Code was falsch... wie gesagt, die Werte ändern sich nicht.

D
78 Beiträge seit 2007
vor 16 Jahren

Original von digi333
die ich immer habe... ist Pix[3] das gleiche wie Pix[0] vom zweiten Pixel?

Genau! Der Aufbau des Arrays sieht ja folgend aus:


 0 R
 1 G
 2 B

 3 R
 4 G
 5 B

 6 R
 7 G
 8 B

 9 R
10 G
11 B

Je drei Byte entsprechen einen Pixel (drei Farbkanäle á 1 Byte pro Kanal). D.h. die Rotwerte der Pixel sind an den Indice 0, 3, 6, 9 zu finden.

Original von digi333
und wie ist unterschied zwischen []-Operator und *Wert?

In der Zeigerarithmetik bedeutet Beides, das der Zeiger dereferenziert wird (du bekommst den gezeigten Wert zurück). Beim []-Operator kannst du zusätzlich den Index angeben. Entsprechend wäre


p[ 0 ] => *( p+0 );
p[ 1 ] => *( p+1 );
p[ 2 ] => *( p+2 );
...
p[ n ] => *( p+n );

Gruß

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo digi333,

ist Pix[3] das gleiche wie Pix[0] vom zweiten Pixel?

ja

und wie ist unterschied zwischen []-Operator und *Wert?

p_ ist das gleiche wie *(p+i)

herbivore

D
digi333 Themenstarter:in
290 Beiträge seit 2006
vor 16 Jahren

**:::