Ciao a tutti, mi sono appena iscritto e ho un problemino con gli header BMP. Volevo imparare a scrivere immagini bmp in c++ e così ho fatto un programmino di prova dove ho riprodotto la struttura dell'header seguendo lo schema di wikipedia. Questo programmino ti fa inserire le dimensioni dell'immagine e la genera riempiendola di rosso. Il problema è che per qualche strano motivo se l'immagine supera i 51x51 il programma comincia a comportarsi in modo strano:
51x51 = immagine corrotta
52x52 e oltre = si vede ma i pixel sono tutti sfasati (ogni riga di pixel è di un colore diverso, suppongo che manchi qualche byte da qualche parte che fa sfasare tutto)
Inizialmente ho pensato che l'array dei pixel si fosse incasinato, ma stampandolo sembra tutto a posto. Non riesco proprio a capire quale sia il problema, eccovi il source:
pastebin ---> Click
codice:
#include <iostream>
#include <stdio.h>
#include <conio.h>
using namespace std;
#pragma pack(1) // Serve a non far sfasare l'allineamento dei byte
struct BITMAP_HEADER {
struct BITMAPFILEHEADER {
unsigned short signature;
unsigned long size;
unsigned short reserved1;
unsigned short reserved2;
unsigned long file_offset;
} bmp_header;
struct BITMAPV5HEADER {
unsigned long header_size;
unsigned long width;
unsigned long height;
unsigned short planes;
unsigned short bit_per_pix;
unsigned long compression;
unsigned long image_size;
unsigned long x_pix_per_m;
unsigned long y_pix_per_m;
unsigned long colors;
unsigned long important_colors;
} dib_header;
};
struct PIXEL {
unsigned char b;
unsigned char g;
unsigned char r;
};
#pragma pack()
int main() {
unsigned long width, height, imagesize;
PIXEL *pixels;
FILE *file;
cout << "Inserisci la larghezza dell'immagine: ";
cin >> width;
cout << "Inserisci l'altezza dell'immagine: ";
cin >> height;
imagesize = width*height;
cout << "\nPopolando i pixel... ";
pixels = new PIXEL[imagesize];
for(int i=0; i<imagesize; i++){
pixels[i].r = 0xFF; // Rosso
pixels[i].g = 0;
pixels[i].b = 0;
}
cout << "Fatto!\n";
cout << "Generando l'header... ";
BITMAP_HEADER header;
unsigned short padding = 0; // Padding, separatore delle righe
// BMP Header
header.bmp_header.signature = 0x4D42; // BM (Windows)
header.bmp_header.size = sizeof(header) + sizeof(PIXEL)*imagesize + sizeof(padding)*height + 2;
header.bmp_header.reserved1 = 0;
header.bmp_header.reserved2 = 0;
header.bmp_header.file_offset = 54;
// DIB Header
header.dib_header.header_size = 40;
header.dib_header.width = width;
header.dib_header.height = height;
header.dib_header.planes = 1;
header.dib_header.bit_per_pix = 24;
header.dib_header.compression = 0; // BI_RGB
header.dib_header.image_size = sizeof(PIXEL)*imagesize + sizeof(padding)*height;
header.dib_header.x_pix_per_m = 2835;
header.dib_header.y_pix_per_m = 2835;
header.dib_header.colors = 0;
header.dib_header.important_colors = 0;
cout << "Fatto!\n";
cout << "Creando il file... ";
file = fopen("test.bmp", "wb");
if(file != NULL){
cout << "Creato!\n";
// Header
cout << "Scrivendo l'header su file... ";
fwrite (&header, sizeof(header), 1, file); // Resto dell'Header
cout << "Fatto! (" << sizeof(header) << " bytes)\n";
// Pixels
cout << "Scrivendo l'immagine... ";
unsigned long pos = width * height; // Parte dall'ultima riga di pixels
while (pos != 0) {
for (unsigned long n = 0; n<width; n++) // Scrive tutti i pixel della riga
fwrite (&pixels[pos - width + n], sizeof(PIXEL), 1, file);
fwrite (&padding, sizeof(padding), 1, file); // 2 Bytes di Padding
pos -= width; // Va indietro di una riga
}
cout << "Fatto! (" << header.dib_header.image_size << " bytes)\n";
cout << "Dimensione totale file: " << header.bmp_header.size << " bytes.\n";
} else cout << "Errore Scrittura!\n";
delete[] pixels;
getch();
return 0;
}