Newsgroup: it.comp.lang.c++
Titolo: Conversione RAW -> BMP

Ciao a tutti,
avrei urgente bisogno di una routine in C in grado di convertire una
immagine RAW (RGB) in Windows BMP.
La routine dovrebbe essere in grado di convertire l'immagine quando e'
ancore presente in memoria, sotto forma di matrice (ma va bene anche
se l'immagine viene letta da file).
L'immagine RAW viene memorizzata come Matrice.
La struttura utilizzata e':
struct punto
 {
   unsigned char R;
   unsigned char G;
   unsigned char B;
}
struct punto Immagine[Righe][Colonne]
Preferirei avere un sorgente, ma se doveste avere solo l'eseguibile di
un file capace di fare quanto detto (e, magari, POCO altro), mandatelo
pure nel NewsGroup.
Il tutto dovrebbe preferibilmente essere compilabile con il DJGPP per
DOS.
Grazie a tutti

Il tutto dovrebbe preferibilmente essere compilabile con il DJGPP per
Mah, il DJGPP non lo conosco, comunque ecco una routinetta all'acqua
di rose che forse potrebbe fare al caso tuo; e` in un C++ "quasi C",
usa solo le piccole comodita` del formato-commenti e deelle dichiarazioni
inframmiste alle istruzioni -- penso che il tuo DJGPP la compilera`.
Ecco il sorgente mkbmp.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
typedef unsigned char byte;
struct punto { byte R, G, B; };
// mk_bmp: scrive un file .BMP da un'immagine R-G-B in memoria
// Torna FALSE in caso di errore, TRUE se ha funzionato bene.
BOOL
mk_bmp(
    const char * filename,  // path completo del file XX.BMP da scrivere
    int width, int height,  // larghezza e altezza, in pixel
    punto *immagine         // width*height punti, organizzati per righe
    )
{
    // un file .BMP e` composto da:
    // -- una struttura BITMAPFILEHEADER, seguita da
    // -- una struttura BITMAPINFOHEADER, e infine
    // -- l'immagine, per righe, con origine in basso a sinistra,
    //    24 bit/pixel nell'ordine B-G-R con 1 byte per componente
    //
    // i bytes/riga devono sempre essere un multiplo di 4
    // (per l'allineamento alla doubleword).  Calcoliamoli:
    int byLine = width*3;
    if(byLine&3) { byLine|=3; ++byLine; }
    // prepariamo l'header di file:
    BITMAPFILEHEADER bf;
    memset(&bf, 0, sizeof(bf));     // vari campi devono essere 0
    memcpy(&bf.bfType, "BM", 2);    // segno necessario di "tipo-file"
    // dimensione in byte del file:
    bf.bfSize = sizeof(bf) + sizeof(BITMAPINFOHEADER) +
        byLine*height;
    // offset (in byte) all'inizio dei dati sui pixel
    bf.bfOffBits = sizeof(BITMAPINFOHEADER);
    // prepariamo l'header di bitmap:   
    BITMAPINFOHEADER bi;
    memset(&bi, 0, sizeof(bi));
    bi.biSize = sizeof(bi);
    bi.biWidth = width;
    bi.biHeight = height;
    bi.biPlanes = 1;
    bi.biBitCount = 24;
    // apriamo il file e scriviamo gli header:
    FILE *f = fopen(filename, "wb");
    if(!f) return FALSE;
    fwrite(&bf, 1, sizeof(bf), f);
    fwrite(&bi, 1, sizeof(bi), f);
    // scriviamo i dati sui colori dei pixel:
    byte *b = (byte*)malloc(byLine);
    memset(b, 0, byLine);
    punto *pi = immagine;
    for(int y=0; y<height; ++y) {
        byte *pb = b;
        for(int x=0; x<width; ++x) {
            *pb++ = pi->B;
            *pb++ = pi->G;
            *pb++ = pi->R;
            ++pi;
        }
        fwrite(b, 1, byLine, f);
    }
    // fine -- operazioni conclusive
    fclose(f);
    free(b);
    return TRUE;
}
Ed eccone un esempietto d'uso, un programma che prepara una
bitmappucola 'artificiale' con bordi verticali rossi, orizzontali
verdi, vertici gialli, e un rettangolo grigio scuro grosso
modo nell'angolo in basso a sinistra di uno sfondo nero -- e`
il file main.cpp (di una Console Application):
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char byte;
struct punto { byte R, G, B; };
// mk_bmp: scrive un file .BMP da un'immagine R-G-B in memoria
// Torna FALSE in caso di errore, TRUE se ha funzionato bene.
int
mk_bmp(
    const char * filename,  // path completo del file XX.BMP da scrivere
    int width, int height,  // larghezza e altezza, in pixel
    punto *immagine         // width*height punti, organizzati per righe
    )
;
struct punto immagine[30][25];
int main()
{
    for(int i=0; i<30; ++i) {
        immagine[i][0].R = 255;
        immagine[i][24].R = 255;
    }
    for(int j=0; j<25; ++j) {
        immagine[0][j].G = 255;
        immagine[29][j].G = 255;
    }
    for(int k=3; k<12; ++k) {
        for(int l=3; l<15; ++l) {
            immagine[k][l].R = 150;
            immagine[k][l].G = 120;
            immagine[k][l].B =  90;
        }
    }
 
    mk_bmp("D:\\pippo.bmp", 25, 30, &immagine[0][0]);
    return 0;
}
Facci sapere se questo ti risolve il problema...!
Alex
--
 ____    Alex Martelli, Bologna, Italia -- email: 
al...@magenta.com
 \SM/___                                 
http://magenta.com/~alex
  \/\bi/     You never know what is enough unless you know what
     \/          is more than enough.