Operacje wejścia/wyjścia na plikach binarnych różnią się w kilku istotnych szczegółach od operacji opisanych powyżej. Z reguły, aby odczytać plik binarny (bitmapę, plik audio itp.), musimy znać jego strukturę, tzn. znaczenie poszczególnych bajtów pliku. Te informacje są zawsze zawarte w specyfikacji formatu, a środowiska programistyczne udostępniają zbiory funkcji do obsługi danych formatów.
Rys. 1 Bitmapa 256 kolorowa o rozmiarze 100 na 100 pikseli
Jednym z prostszych do obsługi formatów jest format BMP. Pierwsze 1078 bajtów bitmapy 254 kolorowej zawiera nagłówek a w nim mi.in.informacje o wielkości bitmapy i o używanej palecie barw. Kolejne bajty bitmapy to kolory przyporządkowane do poszczególnych pikseli obrazu, o którym możemy myśleć jak o tablicy dwuwymiarowej. Przedstawiony poniżej kod prezentuje czytanie bitmapy 256 kolorowej (np. takiej jak na Rys. 1).
1. #include <stdio.h>
2. #include <stdlib.h>
3.
4. int main(int argc,char *argv[])
5. {
6. FILE *strm;
7. int i,j,N;
8. char ch,naglowek[1078];
9. int obraz[200][200];
10.
11. N=atoi(argv[2]);
12.
13. strm=fopen(argv[1],"rb");
14. for(i=0;i<1078;i++)
15. {
16. ch=fgetc(strm);
17. naglowek[i]=ch;
18. }
19. for(i=0;i<N;i++)
20. for(j=0;j<N;j++)
21. {
22. fread(&ch,sizeof(char),1,strm);
23. obraz[i][j]=ch;
24. }
25. fclose(strm);
26. }
Bitmapa jest otwierana w trybie do odczytu w linii 13 - tryb "rb"oznacza, że do odczytu jest otwierany plik binarny. Pętla for (linie 14 - 18) odczytuje nagłówek bajt po bajcie, z wykorzystaniem funkcji fgetc(). Funkcja ta odczytuje dokładnie jeden bajt i dlatego wynik trafia do zmiennej znakowej ch. W kolejnych pętlach (linie 19-24) czytane są kolejne bajty pliku, a przeczytane wartości trafiają do dwuwymiarowej tablicy obraz. Jeśli z pliku chcemy odczytać więcej niż jeden bajt na raz, możemy użyć funkcji fread() (linia 22). Instrukcje zapisane w liniach 16 i 22 są równoważne - obie odczytują jeden bajt z pliku wejściowego. Odczytanie z binarnego pliku wejściowego liczby typu int mogłoby być zrealizowane instrukcją:
int liczbaInt;
fread(&liczbaInt,sizeof(int),1,strm);
Zapisanie jednego bajtu danych do pliku otwartego do pisania binarnego (fopen(nazwa,"wb")) realizuje się funkcją fputc(). Zapisanie danych dowolnego typu realizuje się funkcją fwrite().
Uwaga: przedstawiony powyżej kod czyta poprawnie tylko bitmapy 256 kolorowe, których szerokość jest całkowitą wielokrotnością liczby 4.
Proszę napisać program czytający bitmapę przedstawioną na Rys. 1, wypełniający ją kolorem podanym z linii komend (w zakresie od 0 do 255) i zapisującym efekt tej operacji do pliku bitmapy o nazwie podanej z linii komend.
Proszę napisać program do manipulacji kontrastem na bitmapach 256 kolorowych. Program ma wczytać bitmapę o nazwie pobranej z linii komend, wyświetlić aktualny kolor minimalny i maksymalny w bitmapie, odczytać z klawiatury nowy kolor minimalny i maksymalny (w zakresie od 0 do 255), a następnie przeskalować wszystkie kolory do nowego zakresu wg wzoru:
nowyKolor = noweMinimum + (staryKolor - stareMinimum)*(noweMaksimum - noweMinimum)/(stareMaksimum - stareMinimum)
Bitmapę z przeskalowanymi kolorami należy zapisać do pliku o nazwie pobranej z linii komend.
Proszę napisać program wyznaczający składowe gradientu obrazu zapisanego w bitmapie.
Proszę zapoznać się ze strukturą nagłówka bitmapy i zaprojektować strukturę danych w której taki nagłówek będzie przechowywany i wykorzystanie której umożliwi pisanie i czytanie dowolnej bitmapy.