Jeśli jesteś właścicielem tej strony, możesz wyłączyć reklamę poniżej zmieniając pakiet na PRO lub VIP w panelu naszego hostingu już od 4zł!
2013-10-09    Programowanie, C++, WinAPI, Bitmapa, Kod

Chciałbym przedstawić programik(który już jakiś czas temu napisałem) generujący czarno-biało bitmapę. Program przyjmuje plik formatu *.sb(tj. Szewy Bitmap) i na jego wzorze tworzy bitmapę.

Budowę pliku *.sb:
        0000-0003: SB00                  ; Sygnatura
        0004-0005: sizeX sizeY         ; Wielkość x i y(4-255)
        0006-....: [0|1]*sizeX*sizeY  ; 0(white) lub 1 (black) - kolor danego pixala

Program konwertujący plik .sb do .bmp:
 
    #include <iostream>
    #include <fstream>
    #include <windows.h>
 
    using namespace std;
 
    union size
    {
        char temp;
        unsigned char u;
    };
 

Z unii korzystam przy odwoływaniu się do tego samego znaku zarówno jako char, jak i unsigned char.
 
    int main(int argc, char *argv[])
    {
        if(argc != 2)
          return -1;
 
        //Variables
        fstream input(argv[1], ios::in | ios::binary);
        char temp[4];
        size sizeX;
        size sizeY;
        unsigned int  sizeOfFile;
        char tab[0xFF][0xFF];
 

Pierwszy warunek sprawdza czy został podany plik *.sb. Kolejno znajdują się definicje zmiennych użytych programie.
 
    //Size of file
    input.seekg(0, ios::end);
    sizeOfFile  = input.tellg();
    input.seekg(0, ios::beg);
 
    //Checking size of file
    if(sizeOfFile < 22)
        return 1;
 
    //Signature
    input.get(temp[0]);
    input.get(temp[1]);
    input.get(temp[2]);
    input.get(temp[3]);
 
    if(temp[0] != 'S' || temp[1] != 'B' || temp[2] != '\0' || temp[3] != '\0')
        return 2;
 
    //Size of bitmap
    input.get(sizeX.temp);
    input.get(sizeY.temp);
 
    if(sizeOfFile != 6u+sizeX.u*sizeY.u)
        return 3;
 
    //Filling array values from file
    for(unsigned char i = 0; i < sizeY.u; i++)
        for(unsigned char j = 0; j < sizeX.u; j++)
        {
            input.get(tab[i][j]);
 
            if(tab[i][j] != '0' && tab[i][j] != '1')
                return 4;
        }
 

Sprawdzenie wielkości pliku, a następnie odczytanie sygnatury. Pętla zaś wypełnia macierz pobranymi kolorami.
 
    //Graphical interpretation
    unsigned char p[sizeY.u][sizeX.u][3];
    string filename;
 
    for(unsigned int i = 0;i < strlen(argv[1]); i++)<br />
    {
        if(argv[1][i] == '.')
          break;
 
        filename +=argv[1][i];
    }
 
    filename += "SB.bmp";
 
    BITMAPFILEHEADER bfh;
    BITMAPINFOHEADER bih;
    FILE *f = fopen(filename.c_str(), "wb");
 
    bfh.bfType          = 0x4D42;
    bfh.bfSize          = sizeof(bfh) + sizeof(bih) + 3 * sizeX.u * sizeY.u;
    bfh.bfReserved1     = 0;
    bfh.bfReserved2     = 0;
    bfh.bfOffBits       = sizeof(bfh) + sizeof(bih);
 
    bih.biSize          = sizeof(bih);
    bih.biWidth         = sizeX.u;
    bih.biHeight        = sizeY.u;
    bih.biPlanes        = 1;
    bih.biBitCount      = 24;
    bih.biCompression   = BI_RGB;
    bih.biSizeImage     = 0;
    bih.biXPelsPerMeter = 3780;
    bih.biYPelsPerMeter = 3780;
    bih.biClrUsed       = 0;
    bih.biClrImportant  = 0;
 

Wyznaczanie wyjściowej nazwy bitmapy, następnie wypełnienie dwóch struktur, które są odpowiedzialne za nagłówki pliku bmp. Dokładny opis: link
 
    for (int i = 0; i < sizeY.u; i++)
    {
        for (int j = 0; j < sizeX.u; j++)
        {
            unsigned char color = 0xFF;
 
            if(tab[i][j] == '1')
              color = 0;
 
            p[i][j][0] = color;
            p[i][j][1] = color;
            p[i][j][2] = color;
        }
    }
 
    fwrite(&bfh, 1, sizeof(bfh), f);
    fwrite(&bih, 1, sizeof(bih), f);
 
    for (int y = sizeY.u-1; y >= 0; y--)
    {
        for (int x = 0; x < sizeX.u; x++)
        {
            fputc(p[y][x][2], f);<br />
            fputc(p[y][x][1], f);<br />
            fputc(p[y][x][0], f);<br />
        }
    }
 
    return 0;
}
 

Ostatni fragment kodu jest odpowiedzialny za zapisanie wszystkich nagłówków pliku .bmp.

Plik *.sb można wygenerować losowo i otrzymać efekty jak poniżej:
Dodaj komentarz:
Nick:
URL(opcjonalnie):