rgb nach rgbx?



  • Hallo,

    ich habe ein RGB-Bild (3 Byte). Das möchte ich in einem Puffer speichern, welcher aber nur RGBX akzeptiert. Dort hat dann jeder Pixel 4 Byte, so wie ich das verstanden habe.

    Ich habe es so versucht:

    //Bildgröße soll zB 100x100 sein 
    //endImageBuf ist ein Zeiger auf die erste Stelle im engültigen Puffer, in den das Bild am Ende rein soll
    
    imageSize = x * y * bytesProPixel;       //Bildgröße gesamt
    
    tempBuffer = (char*) malloc (imageSize);    temporärer Puffer 
    
    ImageBuffer = funktionDieDasBildLiefert(); //im Rgb Format vorliegendes Bild
    
    memcpy(tempBuffer , ImageBuffer , imageSize);
    
    for(i = 0; i < 100; i++)
    {
      memcpy(endImageBuf, tempBuffer[i], 3);   //kopiert 3 Bytes in den engültigen Puffer
      *endImageBuf++;                   
    }
    

    Es wäre schön, wenn mir jemand helfen könnte. Wie kann ich es richtig machen?

    Danke im Voraus!



  • Hi!

    Wenn deine Pixeldaten schon in ImageBuffer sind, brauchst du sie ja nicht extra in tempBuffer zu kopieren.
    Für die Umwandlung nach 4 Byte pro Pixel bleibt dir nichts anderes übrig, als Pixelweise zu kopieren.
    Man kann die Pixel wie in einem Koordinatensystem mit x- und y-Koordinaten adressieren.
    Bedenke, das jede Bildzeile Füllbytes ( Nullbytes ) haben kann.



  • Big Brother schrieb:

    Für die Umwandlung nach 4 Byte pro Pixel bleibt dir nichts anderes übrig, als Pixelweise zu kopieren.

    Hm, ok, tue ich das nicht aber schon in der for-Schleife? Was meinst Du sonst damit?

    Big Brother schrieb:

    Man kann die Pixel wie in einem Koordinatensystem mit x- und y-Koordinaten adressieren.

    Wie meinst Du das genau? Ich kann mir schon vorstellen, dass es so funktioniert, aber wie mans umsetzt... sorry, ich habe immer noch keine Ahnung. 😕



  • pommes schrieb:

    Big Brother schrieb:

    Für die Umwandlung nach 4 Byte pro Pixel bleibt dir nichts anderes übrig, als Pixelweise zu kopieren.

    Hm, ok, tue ich das nicht aber schon in der for-Schleife? Was meinst Du sonst damit?

    Nein, das tust du durchaus nicht. Im Moment kopierst du alles an den Anfang des Puffers und imkrementierst den ersten Teil (weiß nicht was für ein Typ 'endImageBuf' ist).



  • tempBuffer = (char*) malloc(imageSize);
    ImageBuffer = funktionDieDenBufferInitialisiert(tempBuffer, imageSize)
    

    Ich würde gerne mit den eckigen Klammern auf die einzelnen Bytes von tempBuffer zugreifen, aber dabei stürzt das Programm mit "Die Anweisung im Speicherbereich..... ->Ok, Programm beenden" ab.

    David_pb schrieb:

    ..(weiß nicht was für ein Typ 'endImageBuf' ist).

    BYTE *endImageBuf;

    Also so, wie ich das verstehe, ist endImageBuf ein Zeiger auf den Anfang des Speicherbereiches, in dem das Bild liegt.

    for(i = 0; i < 100; i++)
    {
      memcpy(endImageBuf, tempBuffer[i], 3);
      *endImageBuf++;                  
    }
    

    Ich dachte, mit "*endImageBuf++;" inkrementiere ich den Zeiger, so dass ich im nächsten Durchlauf nichts überschreibe, sondern an den Buffer dranhänge sozusagen..?!

    Tut mir leid, wenn ich damit nerve, aber ich komme einfach nicht weiter...sind meine Aussagen richtig? Wie macht man es ansonsten?



  • pommes schrieb:

    Hm, ok, tue ich das nicht aber schon in der for-Schleife? Was meinst Du sonst damit?

    Ich nehme an tempBuffer ist ein unsigned/signed char? Dann kopierst du zwar 3 Byte pro Durchlauf, aber nicht richtig.
    Es werden Bytes mehrfach überlappend kopiert. Wenn dann müsstest du die Adresse von tempBuffer jeweils um 3 Byte und nicht bloss um 1 Byte inkrementieren.
    Die Variable endImageBuf muss nach jedem Pixel-Kopiervorgang 4 Bytes weiter rücken.
    Also so: endImageBuf += 4, Datentyp char bzw. unsigned char angenommen.

    Ausserdem kopierst du nicht das komplette Bild, sondern nur ein hundertstel.
    Es müssen 100*100*3 Bytes kopiert werden.

    Selbst wenn die Schleife richtig wäre, würdest du bei Bildern mit Nullbytes unerwünschte Effekte bekommen, weil diese Nullbytes an Stellen kopiert würden, die eigentlich Farbinformationen bekommen sollten.

    pommes schrieb:

    Wie meinst Du das genau? Ich kann mir schon vorstellen, dass es so funktioniert, aber wie mans umsetzt... sorry, ich habe immer noch keine Ahnung. 😕

    Angenommen data ist ein Zeiger auf den Anfang der Pixeldaten einer Bitmap, die sich im Speicher befindet.
    Die Variable data ist vom Typ unsigned char*.
    Dann brauchst du noch die Höhe, die Breite des Bildes und die Größe in Byte, inklusive der eventuell vorhandenen Nullbytes.
    Die Anzahl der Bits pro Pixel ist in bit_count gespeichert.

    Einen Pixel adressierst du so:

    // Adressierung eines Pixel im RAM.
    // CHAR_BIT hat meistens den Wert 8, deklariert in LIMITS.H
    data + y * size_image / height + x * bit_count / CHAR_BIT;
    

    In zwei for-Schleifen kannst du mit obiger Adressierung das komplette Bild pixelweise durchlaufen, ohne dir über die Nullbytes Gedanken machen zu müssen.
    Die müssen bei der Berechnung der Bildgröße ( size_image ) berücksichtigt sein und werden in der Schleife bedingt durch das Adressierungsprinzip automatisch ignoriert bzw. übersprungen.

    // Schleifengerüst für das Durchlaufen eine Pixelbitmap.
    for ( y = 0; y < height; y++ )
    {
    	for ( x = 0; x < width; x++ )
    	{
    // Hier adressieren und kopieren.
    	}
    }
    

    Zum Kopieren brauchst du also zwei Zeiger, die in der inneren for- Schleife als Parameter für die memcpy-Funktion dienen und mit denen du die Pixel nach obiger Art adressierst.
    Einmal mit bit_count_old = 24 und einmal mit bit_count_new = 32 als Faktor.


Log in to reply