Pliki graficzne w C/C++ - biblioteka FreeImage
Jakiś czas temu na forum linuxowo.pl pojawił się temat obsługi plików graficznych z programów w C. Ponieważ temat ten jest mi bliski postanowiłem napisać krótki tutorial jak tego dokonać posiłkując się darmową biblioteką FreeImage. Biblioteka FreeImage integruje w sobie dobrodziejstwa wielu innych bibliotek obsługujących pliki graficzne (libjpeg, libpng, …) w postaci prostego, zwięzłego i jednolitego API. Ponieważ opiera się na dobrze sprawdzonych komponentach jest niezawodna i szybka. Dla mnie odkrycie jej było lekarstwem na koszmar obsługi plików graficznych w C/C++. Zapraszam do przeczytania i komentarzy. Chętnie napiszę coś więcej na jej temat, jeśli będzie taka potrzeba.
Do tutoriala użyłem mojego Debiana Lennego, ale z powodzeniem powinno to wszystko działać także pod Ubuntu czy ogólnie dowolnym Linuksem. Pod systemem Windows także można użyć biblioteki FreeImage, lecz trzeba mieć kompilator (np. z Visual Studio C++ Express), ręcznie poustawiać kilka rzeczy i oczywiście sciągnąć bibliotekę.
Przygotowanie środowiska
Tutaj sprawa jest niezwykle prosta i sprowadza się do zainstalowania odpowiednich pakietów. Będziemy potrzebować dwóch z nich. Pierwszy to build-essential, który zawiera wszystkie potrzebne nagłówki standardowych bibliotek. Drugi to pakiet samej biblioteki o nazwie libfreeimage-dev. Instalka sprowadza się zatem do:
sudo apt-get install build-essential libfreeimage-dev
Dodam jeszcze, że w Ubuntu pakiet biblioteki FreeImage znajduje się w repozytorium Universe. Należy zatem zadbać o to, aby ów repozytorium było dodane do /etc/apt/sources.list.
Szybki przykład - konwersja formatów

Dla zobrazowania podstaw użycia biblioteki FreeImage rozpatrzymy prosty przykład: konwersję pliku GIF na JPEG. Weźmiemy na warsztat bardzo popularny obraz lenna.gif, który spróbujemy przekonwertować właśnie na JPEGa.
Proponuję zacząć po prostu od kodu:
// freeimage-test.c - przykładowy program używający FreeImage
#include
#include
#include
int main(void)
{
int return_value = EXIT_SUCCESS;
FreeImage_Initialise(TRUE);
puts("Loading...");
FIBITMAP* bitmap = FreeImage_Load(FIF_GIF, "lenna.gif", 0);
if (NULL != bitmap)
{
puts("Saving...");
FreeImage_Save(FIF_JPEG, bitmap, "lenna.jpg", 0);
FreeImage_Unload(bitmap);
}
else
{
puts("Image couldn't be loaded");
return_value = EXIT_FAILURE;
}
FreeImage_DeInitialise();
puts("Exit");
return return_value;
}
No to jedziemy po koleji - co powyższy kod robi:
- używa odpowiednich nagłówków; w przypadku biblioteki FreeImage załączamy plik nagłówkowy
FreeImage.hpoprzedzony dwoma standardowymi nagłówkami biblioteki standardowej języka C - inicjalizuje bibliotekę FreeImage; do tego celu służy wywołanie metody
FreeImage_Initialise(TRUE); bez tego użycie funkcji biblioteki jest niemożliwe - wczytuje plik graficzny w formacie GIF; sprawa jest dość prosta, gdyż wystarczy użyć funkcji
FreeImage_Load; jako parametry podajemy kolejno: typ pliku, jego nazwę oraz zero; jeśli operacja skończy się sukcesem funkcja ta zwróci wskaźnik do strukturyFIBITMAP, która to zawiera wszelkie informacje o wczytanym obrazku; jeśli się to nie powiedzie to dostaniemyNULL - zapisuje plik graficzny w formacie JPEG; sprawa jest analogiczna do wczytywania; używamy w zamian funkcji
FreeImage_Save; tutaj znowu podajemy parametry, czyli: format pliku, wskaźnik do strukturyFIBITMAP, nazwę pliku wyjściowego i znowu zero - zwalnia miejsce zajmowane przez obrazek; właśnie po to jest wywołanie
FreeImage_Unload; jeśli byśmy tego nie uczynili obrazek ciągle by okupował pamięć, co jest już niepotrzebne, bo nie będziemy go więcej używać - deinicjalizuje bibliotekę; gdy już nie potrzebujemy korzystać z usług biblioteki FreeImage należy ją o tym poinformować funkcją
FreeImage_DeInitialise, aby mogła zwolnić pamięć przez siebie zajmowaną
Po więcej informacji zapraszam do oficjalnej dokumentacji FreeImage (znajduje się tam plik PDF).
Kompilacja
Na sam koniec tego mikro-tutoriala instrukcja jak to wszystko skompilować. Użyjemy kompulatora GCC, który jest standardowo dostępny w każdym Linuksie. Skompilować program można np. tak:
gcc freeimage-test.c -lfreeimage -o freeimage-test
Zostanie utworzony plik binarny freeimage-test, a kompilator do linkowania użyje, prócz standardowych bibliotek, także bibliotekę FreeImage (przełącznik -lfreeimage). Po tej całej operacji program jest gotowy do użycia. Wystarczy umieścić plik lenna.gif w katalogu z binarką i uruchomić program. Po tej czynności powinniśmy znaleźć nowy plik lenna.jpg.
Proste? Proste!
Powodzenia w bojach z FreeImage! ![]()
UPDATE: FreeImage posiada także wrapper dla C++, który nieco ułatwia zabawę. Więcej informacji w dokumentacji FreeImagePlus (rzeczony wrapper).


Być może ktoś przeglądając mojego bloga zauważył w odsyłaczach link do strony domowej projektu