Padding-Byte im Windows Bitmap
-
Danke für die schnelle Antwort!
Genau das ist eigentlich meine Frage.Wie kann ich in der for Schleife z.B. zwei Byte mit dem Wert 0 hinzufügen?
int paddingbyte=2; for (row = 0; row < hoehe; row++) { for (gap = 0; gap < breite + paddingbyte; gap++) { fwrite(&array[row][gap], 1, 3, bmp); } }
Jetzt habe ich einfach wieder eine längere Breite?!?!
Ich weiß nicht weiter...LG
-
Neiiiiin, so bekommst du erst recht Datensalat.
So baust du einen Random-Infile-Bitmap-Dublicator.
Die Breite des Bildes in Pixel kennst du, die Anzahl der Paddingbytes kannst du ausrechnenint padding_bytes_count = 0, rest = ( width * 3 ) % 4; if ( rest ) padding_bytes_count = 4 - rest;
Und nach jeder geschriebenen Zeile kommt der Paddingbytes-Check
char padding_bytes[3] = {0}; // ... if ( padding_bytes_count ) fwrite ( padding_bytes, 1, padding_bytes_count, fp );
-
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); }
danke für deine Hilfe!
sollte das jetzt so funktionieren???
liebe Grüße
-
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 okayint 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 willDas ist meistens so, dass man die Anzahl der Bytes vor dem Schreiben kennt.
Es sei denn, man benutzt eine Kristallkugel-Implementationfwrite ( 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 willDas ist meistens so, dass man die Anzahl der Bytes vor dem Schreiben kennt.
Es sei denn, man benutzt eine Kristallkugel-Implementationfwrite ( 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 DWORDAuch 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!