Visualizzazione dei risultati da 1 a 3 su 3
  1. #1

    [C++] Problema con gli Header BMP

    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;
    }

  2. #2
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    Credo che il problema sia nel salvataggio di ogni riga della tua bitmap, se nn sbaglio deve essere multiplo di 2, credo che sia sbagliato il padding.
    Per gli Spartani e Sparta usa spartan Il mio github

  3. #3
    Originariamente inviato da linoma
    Credo che il problema sia nel salvataggio di ogni riga della tua bitmap, se nn sbaglio deve essere multiplo di 2, credo che sia sbagliato il padding.
    Grazie! Finalmente ho capito l'unica cosa che mi mancava del formato bitmap! Il padding arrotonda la dimensione dele righe a multiplo di 4! Bastava fare un padding di 1 byte e scriverlo width%4 volte!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.