ZAWARTOŚCI 3 PLIKOW W WORDZIE: MAIN.CPP: #include <iostream> #include <fstream> #include <string.h> pamięci // Potrzebne do memset oraz memcpy, czyli kopiowania bloków #include "Rysowanie_BMP.h" using namespace std; = void Ustaw_naglowek( unsigned char Naglowek[] ) memset( Naglowek, 0x00, 0x36 ); // Zerujemy tablicę nagłówka, większość pól jest i tak równa zero Naglowek[ 0 ] = 0x42; Naglowek[ 1 ] = 0x4D; unsigned Rozmiar_pliku = Rozmiar_bitmapy_w_pamieci + 0x36; memcpy( &Naglowek[ 2 ], &Rozmiar_pliku, sizeof( Rozmiar_pliku ) ); Naglowek[ 10 ] = 0x36; Naglowek[ 14 ] = 0x28; memcpy( &Naglowek[ 18 ], &Bitmapa_Szerokosc, sizeof( Bitmapa_Szerokosc ) ); memcpy( &Naglowek[ 22 ], &Bitmapa Wysokosc, sizeof( Bitmapa Wysokosc ) ); Naglowek[ 26 ] = 0x01; Naglowek[ 28 ] = 0x18; unsigned Rozmiar_bitmapy = Rozmiar_bitmapy_w_pamieci; memcpy( &Naglowek[ 34 ], &Rozmiar_bitmapy, sizeof( Rozmiar_bitmapy ) ); = int Zapisz_bitmape_do_pliku( unsigned char Naglowek[], unsigned char Bitmapa[], string Nazwa_pliku ) Nazwa_pliku += ".bmp"; fstream Plik_zapisz; Plik_zapisz.open( Nazwa_pliku.c_str(), ios::out ios::binary ); if( Plik_zapisz.good() == false ) cout << "Nie mozna zapisac bitmapy do pliku!" << endl;
Plik_zapisz.close(); return 1; Plik_zapisz.write( (char*)naglowek, 0x36 ); Plik_zapisz.write( (char*)bitmapa, Rozmiar_bitmapy_w_pamieci ); Plik_zapisz.close(); cout << "Bitmape zapisano do pliku o nazwie " << Nazwa_pliku << endl; = int main(int argc, char** argv) unsigned char Naglowek[ 0x36 ]; // Rozmiar nagłówka jest zawsze taki sam, niezeleżnie od wielkości bitmapy. unsigned char *Bitmapa; // Rozmiar tablicy przechowującej samą bitmapę jest zależny od szerokości i wysokości. Rozmiar ten musimy obliczyć wczesniej. // Także nie można tej tablicy zadeklarować jako tablicy statycznej. Przelicz_rozmiar_bitmapy_w_pamieci(); Bitmapa = new unsigned char[ Rozmiar_bitmapy_w_pamieci ]; Ustaw_naglowek( Naglowek ); Rysuj_bitmape( Bitmapa ); Zapisz_bitmape_do_pliku( Naglowek, Bitmapa, "obrazek" ); delete [ ] Bitmapa; Bitmapa = NULL; Mój_obraz.CPP: #include "Moj_obraz.h" #include "Rysowanie_BMP.h" // W pliku znajdują się różne funkcje odpowiedzialne za metody rysowania // Ustawiamy szerokość i wysokość bitmapy. Te zmienne są zadeklarowane w innym pliku. void Ustaw_rozmiar_bitmapy()
Bitmapa_Szerokosc = 400; // Wymiary bitmapy powinny być podzielne przez 4 Bitmapa Wysokosc = 300; // Jeśli nie są, to nic się nie dzieje, tylko inaczej się adresuje tablicę, a to już trudniej zaprogramować // W tej funkcji możemy dowolnie rysować po bitmapie, co tylko nam się podoba // Tak naprawdę używamy trzech funkcji: Rysuj_tlo() - do pokolorowania tła, Ustaw_kolor(...) - wybór koloru, Piksel(...) - postawienie piksela we właściwym miejscu int Rysuj_moj_obraz_na_bitmapie() // Funkcja Ustaw_kolor( Red, Green, Blue ) pozwala na ustawienie koloru aktualnie używanego do malowania pikseli, // wywołujemy ją tylko wtedy, gdy chcemy zmienić kolor na inny niż do tej pory. Ustaw_kolor( 255, 255, 255 ); Rysuj_tlo(); // Malujemy wszystkie piksele na jeden kolor, czyli tworzymy tło // Przykład - czarna ramka wokół obrazu Ustaw_kolor( 0, 0, 0 ); for( int x = 0; x < Bitmapa_Szerokosc; x++ ) Piksel( x, 0 ); Piksel( x, Bitmapa Wysokosc - 1 ); for( int y = 0; y < Bitmapa Wysokosc; y++ ) Piksel( 0, y ); Piksel( Bitmapa_Szerokosc - 1, y ); // Przykład - czerwone piksele w kilku różnych miejscach Ustaw_kolor( 255, 0, 0 ); Piksel( 100, 120 ); Piksel( 230, 100 ); Piksel( 250, 240 ); Piksel( 320, 210 ); // Przykład - linia pionowa koloru ciemno zielonego Ustaw_kolor( 0, 128, 0 ); for( int y = 150; y < 280; y++ ) Piksel( 200, y ); // Przykład - linia pozioma koloru ciemno niebieskiego Ustaw_kolor( 0, 0, 128 ); for( int x = 20; x < 200; x++ ) Piksel( x, 150 );
// Przykład - linia ukośna (45 stopni) koloru ciemno żółtego Ustaw_kolor( 220, 220, 0 ); for( int i = 0; i < 80; i++ ) int x = 200 + i; int y = 150 - i; Piksel( x, y ); // Przykład - linia ukośna dowolnego kątu koloru fioletowego Ustaw_kolor( 224, 0, 224 ); for( int i = 0; i < 180; i++ ) int x = 200 + i; int y = 150 + i / 3; Piksel( x, y ); RYSOWANIE_BITMAPY.CPP: #include "Rysowanie_BMP.h" #include "Moj_obraz.h" // W pliku znajduje się instrukcja odpowiedzialna za ustawienie rozmiaru bitmapy i wywołanie funkcji rysowania wszystkiego #include <string.h> // Potrzebne, bo instrukcja "memcpy()" jest w środku unsigned Bitmapa_Szerokosc = 16; // Wymiary bitmapy ustawiamy w innym pliku unsigned Bitmapa Wysokosc = 16; // Także tu są tylko wymiary domyślne unsigned Rozmiar_bitmapy_w_pamieci; // Często wykorzystywane, obliczane automatycznie podczas tworzenia bitmapy = void Sprawdz_rozmiar_i_napraw_jesli_trzeba( unsigned *Wymiar ) // Proste zabezpieczenie, gdyby ktoś jednak podał rozmiar tablicy niepodzielny przez 4 *Wymiar = ( *Wymiar + 2 ) / 4 * 4; // Zabezpieczenie, jeśli ktoś poda zerowy lub zbyt duży rozmiar if( *Wymiar == 0 ) *Wymiar = 4; else if( 4096 < *Wymiar ) *Wymiar = 4096;
void Przelicz_rozmiar_bitmapy_w_pamieci() Ustaw_rozmiar_bitmapy(); Sprawdz_rozmiar_i_napraw_jesli_trzeba( &Bitmapa_Szerokosc ); Sprawdz_rozmiar_i_napraw_jesli_trzeba( &Bitmapa Wysokosc ); Rozmiar_bitmapy_w_pamieci = Bitmapa_Szerokosc * Bitmapa Wysokosc * 3; = // Struktura ułatwia zarządzanie zmiennymi R, G, B struct skolor unsigned char R; unsigned char G; unsigned char B; ; skolor Kolor; // Deklaracja zmiennej typu struktura unsigned char *g_bmp; // Globalny wskaźnik na tablicę( bitmapę ), żeby nie trzeba było jej za każdym razem w funkcji przekazywać jako parametr // Funkcja ustawiająca zmienne w strukturze, bardzo ułatwia zarządzanie danymi void Ustaw_kolor( unsigned char R, unsigned char G, unsigned char B ) Kolor.R = R; Kolor.G = G; Kolor.B = B; // Funkcja maluje piksel o współrzędnych x i y na kolor ustawiony wcześniej int Piksel( unsigned x, unsigned y ) // Zabezpieczenie przed niepoprawnymi współrzędnymi, które wychodzą za bitmapę. if( Bitmapa_Szerokosc <= x Bitmapa Wysokosc <= y ) return 1; // Wzór na pozycję - bitmapa to tak naprawdę tablica jednowymiarowa, chociaż my ją widzimy jako dwuwymiarowy obraz, // także na podstawie współrzędnych x i y musimy przeliczyć właściwe miejsce w pamięci gdzie dany piksel się znajduje. int pix = y * Bitmapa_Szerokosc + x;
// Mnożymy przez 3, bo paleta RGB i każdy piksel ma po 3 bajty. pix *= 3; // Pokoloroanie właściwego piksela kolorami RGB g_bmp[ pix + 0 ] = Kolor.B; g_bmp[ pix + 1 ] = Kolor.G; g_bmp[ pix + 2 ] = Kolor.R; // Funkcja malująca wszystkie piksele bitmapy na ten sam kolor - czyli tworząca tło void Rysuj_tlo() // Malujemy jeden piksel w rogu na właściwy kolor. Piksel( 0, 0 ); unsigned Szer_x3 = 3 * Bitmapa_Szerokosc; // Kopiujemy pomalowany piksel tyle razy ile jest pikseli na szerokość (na jeden piksel przypadają po 3 bajty, stąd te skoki co 3 ). for( int x = 1; x < Szer_x3; x += 3 ) memcpy( &g_bmp[ x ], &g_bmp[ 0 ], 3 ); // Kopiujemy pokolorowaną całą linię tyle razy ile jest linii na wysokość. for( int y = 1; y < Bitmapa Wysokosc; y++ ) memcpy( &g_bmp[ y * Szer_x3 ], &g_bmp[ 0 ], Szer_x3 ); // Główna funkcja rysująca int Rysuj_bitmape( unsigned char Bitmapa[] ) // Przypisanie adresu bitmapy do naszego wskaźnika, żeby nie trzeba było za każdym razem wywoływać jako parametr funckji. g_bmp = Bitmapa; // Główna funkcja rysująca( zadeklarowana w pliku "Moj_obraz.cpp" ). Rysuj_moj_obraz_na_bitmapie();