Padding-Byte im Windows Bitmap



  • Das dürfte wohl vom Rest deines Programms abhängen.
    Hast du dir das Ergebnis etwa noch gar nicht angeguckt? 😮 😕

    Die Definition des char Arrays würde ich nicht mitten in der for Schleife platzieren,
    finde ich iwie nicht schön, aber wenn du das gut findest, ist das okay 😉

    int padding_bytes = 2;
    

    Kannst du natürlich rausschmeißen.



  • oh, ja das hab ich in meinem code gelöscht.
    es funktioniert aber noch immer leider nicht.
    das bild wird richtig ausgegeben, mit einer durch vier teilbaren zahl und mit der zahl darunter (z.B. 11 und 12 funktioniert; 9 und 10 nicht) ...
    an was kann das liegen?
    lg



  • int ByteSize = 54+((weite*3)*breite);
    

    Da müssen die Füllbytes mit rein plus Größe des Infoheaders.



  • Vielen Dank, hat funktioniert!
    Hatte blöderweise deine if in die for-schleife gepackt...
    Danke nochmal!!!
    LG



  • welche if meinst du?
    die zweite muss jedenfalls in die for schleife rein



  • Hallo,
    ich habe die zweite if in die erste for-schleife gegeben.
    D.h, nach jeder Zeile überprüft er, ob if den Wert null hat, wenn nicht hängt er noch die Padding-Bytes an.

    int row;
      int gap;
    
      int padding_bytes = 2;
      int padding_bytes_count = 0;
      int rest = ( breite* 3 ) % 4;
      if (rest)
      padding_bytes_count = 4 - rest;
    
      for (row = 0; row < hoehe; row++)
      {
    
        for (gap = 0; gap < breite; gap++)
        {
          fwrite(&array[row][gap], 1, 3, bmp);
          char padding_bytes[3] = {0}; 
        }
        if ( padding_bytes_count )
        fwrite ( padding_bytes, 1, padding_bytes_count, bmp );  
      }
      fwrite(bytes,1,BytesSize,bmp);  
      fclose(bmp);
    }
    

    Eine Frage hätte ich noch zu fwrite: Muss ich zuerst die 24 Bit-Farbtiefe (3 Byte) schreiben oder danach:

    fwrite(&array[row][gap], 3, 1, bmp);
    

    oder

    fwrite(&array[row][gap], 1, 3, bmp);
    

    Liebe Grüße



  • Was soll denn Zeile 16 machen?

    Ist dir klar, dass das padding_bytes aus Zeile 19 zu Zeile 4 gehört?

    Lies dir doch mal die man page /Referenz zu fwrite durch, dann weisßt du es.
    http://www.cplusplus.com/reference/cstdio/fwrite/



  • so hab ich es gemeint:

    int row;
      int gap;
    
      int padding_bytes_count = 0;
      int rest = ( breite* 3 ) % 4;
      if (rest)
      padding_bytes_count = 4 - rest;
      char padding_bytes[3] = {0};
    
      for (row = 0; row < hoehe; row++)
      {
    
        for (gap = 0; gap < breite; gap++)
        {
          fwrite(&array[row][gap], 1, 3, bmp)
        }
        if ( padding_bytes_count )
        fwrite ( padding_bytes, 1, padding_bytes_count, bmp );  
      }
      fwrite(bytes,1,BytesSize,bmp);  
      fclose(bmp);
    }
    

    war ein kopier-fehler
    lg



  • Die ganze Implementation ist recht wackelig und sehr unflexibel.

    Insbesondere die Berechnung von Grössen sollte flexibler sein.

    int PixelSize = 3;
    
      /* The length of each line must be a multiple of 4 bytes */
      bytesPerLine = (PixelSize * width + 3) / 4 * 4;
    
      bmfh.bfType = "BM";
      bmfh.bfReserved = 0; 
      /* Offset = BITMAPFILEHEADER's size + BITMAPINFOHEADER size + palette array in case of indexed bitmaps  */
      bmfh.bfOffBits = sizeof(bmfh) + sizeof(bmih);  // =54 bei RGB24
      bmfh.bfSize = bmph.bfOffBits + bytesPerLine * height;
    
      bmih.biSize=sizeof(bmih);
    

    Wie man sieht muss man oben schon wissen, was man weiter unten in die Datei
    schreiben will ...

    Edit: Berechnung bytesPerLine korrigiert
    Natürlich könnte man auch shiften oder maskieren ...



  • Nachtrag:

    int padding_bytes_count = bytesPerLine - width*PixelSize;
    


  • merano schrieb:

    Wie man sieht muss man oben schon wissen, was man weiter unten in die Datei
    schreiben will

    Das ist meistens so, dass man die Anzahl der Bytes vor dem Schreiben kennt. 🤡
    Es sei denn, man benutzt eine Kristallkugel-Implementation

    fwrite ( data, ask_crystal_ball(), 1, fp );
    

    merano schrieb:

    Die ganze Implementation ist recht wackelig und sehr unflexibel.

    Weder noch. Aber vielleicht übersehe ich ja etwas, also bitte begründen.

    merano schrieb:

    Insbesondere die Berechnung von Grössen sollte flexibler sein.

    int PixelSize = 3;
      /* The length of each line must be a multiple of 4 bytes */
      bytesPerLine = (PixelSize * (width + 3) / 4) * 4;
    

    Deine Formel ist btw. ein wenig verschwenderisch, denn sie berechnet nicht die kleinstmögliche, durch 4 teilbare Anzahl Bytes.
    Dafür gibt es bessere Möglichkeiten, z.B.

    bytes_per_row = (((image_width_in_pixel * 3) + 3) & 0xFFFC);
    


  • CJosef schrieb:

    merano schrieb:

    Wie man sieht muss man oben schon wissen, was man weiter unten in die Datei
    schreiben will

    Das ist meistens so, dass man die Anzahl der Bytes vor dem Schreiben kennt. 🤡
    Es sei denn, man benutzt eine Kristallkugel-Implementation

    fwrite ( data, ask_crystal_ball(), 1, fp );
    

    Obwohl Du dem Threadersteller bereits mitgeteilt hast:

    CJosef schrieb:

    int ByteSize = 54+((weite*3)*breite);
    

    Da müssen die Füllbytes mit rein plus Größe des Infoheaders.

    berechnet er die Paddingbytes zu spät. (Nachdem er sie bereits geschrieben hat ..). Ich wollte auf diesen Umstand nochmal explizit hinweisen.

    CJosef schrieb:

    merano schrieb:

    Die ganze Implementation ist recht wackelig und sehr unflexibel.

    Weder noch. Aber vielleicht übersehe ich ja etwas, also bitte begründen.

    Feste Groessen wo eigentlich sizeof hingehört, Groesse 54 z.B. nicht berechnet.
    Siehe auch Kommentare Wikipedia. Wenn die Entwickler sicher gewesen wären, das
    sich die Strukturen nie ändern werden hätten sie das nicht so implementiert.

    CJosef schrieb:

    Deine Formel ist btw. ein wenig verschwenderisch, denn sie berechnet nicht die kleinstmögliche, durch 4 teilbare Anzahl Bytes.
    Dafür gibt es bessere Möglichkeiten, z.B.

    bytes_per_row = (((image_width_in_pixel * 3) + 3) & 0xFFFC);
    

    Ups, copy and paste Fehler - die Klammer ist tatsächlich an der falschen Stelle.
    Das besser ich natürlich sofort nach ...

    Die Lösung mit einer Bitmaske ist wirklich besser - solange das Ergebnis nicht groesser als 0xFFFC wird ...
    Bei bfSize handelt es sich z.B. immerhin um ein DWORD 😉



  • merano schrieb:

    Feste Groessen wo eigentlich sizeof hingehört, Groesse 54 z.B. nicht berechnet.
    Siehe auch Kommentare Wikipedia. Wenn die Entwickler sicher gewesen wären, das
    sich die Strukturen nie ändern werden hätten sie das nicht so implementiert.

    Ah, okay. Ich hatte nur meinen Senf im Sinn 😃
    Ja, stimmt die 54 sollte man nicht hart codieren.

    merano schrieb:

    Ups, copy and paste Fehler - die Klammer ist tatsächlich an der falschen Stelle.
    Das besser ich natürlich sofort nach ...

    Welche Klammer?

    merano schrieb:

    Die Lösung mit einer Bitmaske ist wirklich besser - solange das Ergebnis nicht groesser als 0xFFFC wird ...
    Bei bfSize handelt es sich z.B. immerhin um ein DWORD 😉

    Auch wieder wahr, da hab ich ja mal gar nicht dran gedacht.
    Stimmt, das geht besser:

    bytes_per_row = 4 * (( width * bits_pixel + 31) / 32);
    


  • CJosef schrieb:

    merano schrieb:

    Ups, copy and paste Fehler - die Klammer ist tatsächlich an der falschen Stelle.
    Das besser ich natürlich sofort nach ...

    Welche Klammer?

    s.o.

    CJosef schrieb:

    Auch wieder wahr, da hab ich ja mal gar nicht dran gedacht.
    Stimmt, das geht besser:

    bytes_per_row = 4 * (( width * bits_pixel + 31) / 32);
    

    Wie bitte ?

    Wenn Du uns nun noch schnell erklärst wieso bei einem 4 Byte Alignment 31 addiert werden soll 😕



  • merano schrieb:

    CJosef schrieb:

    merano schrieb:

    Ups, copy and paste Fehler - die Klammer ist tatsächlich an der falschen Stelle.
    Das besser ich natürlich sofort nach ...

    Welche Klammer?

    s.o.

    mir ist auch nicht ersichtlich um welche klammer es geht. wie wärs mal wenn du die deiner meinung nach korrekte formel postest statt klugzuschei... ? 🙄

    merano schrieb:

    CJosef schrieb:

    Auch wieder wahr, da hab ich ja mal gar nicht dran gedacht.
    Stimmt, das geht besser:

    bytes_per_row = 4 * (( width * bits_pixel + 31) / 32);
    

    Wie bitte ?

    Wenn Du uns nun noch schnell erklärst wieso bei einem 4 Byte Alignment 31 addiert werden soll 😕

    offengesichtlich wird hier mit der einheit bit gerechnent.
    ein byte(meist) 8 bit sind
    http://de.wikipedia.org/wiki/Byte
    ist das wirklich so schwer 🙄



  • brainpadding schrieb:

    offengesichtlich wird hier mit der einheit bit gerechnent.

    Bin-go! 👍


Anmelden zum Antworten