Доброго времени суток!
Все время очень сильно привлекала внимание обработка изображений (алгоритмы сжатия, фильтры и т.д.). Увы, сложилось так, что работа практически не связана ни с обработкой изображений, ни с программированием вообще. Тем не менее, интерес к любимому делу не уменьшился и поэтому хочу представить Вашему вниманию недавно открытую для себя библиотеку CImg.
CImg – библиотека C++, предоставляющая классы и функции обработки изображений. Это как элементарные функции (загрузка, сохранение, просмотр), так и алгоритмы для изменения размера/вращения, применения эффектов, отрисовки объектов (текста, линий, поверхностей, элипсов, ...), и т.д.
Структура библиотеки
Библиотека состоит из одного заголовочного файла CImg.h, который включает в себя все классы и функции CImg. В этом отличительная черта библиотеки, в чем есть некоторые плюсы:
- отсутствие необходимости предварительной компиляции библиотеки, поскольку CImg-код компилируется (извините за тавтологию :-) во время компиляции основной программы, включающей в себя CImg.h;
- отсутствие сложных зависимостей: просто включаем CImg.h в свой проект;
- компиляция происходит «на лету»: в исполняемый файл включается только та функциональность, которая используется в программе. Это позволяет создавать очень компактные приложения;
- члены классов и функции являются встраиваемыми (inlined), что приводит к более высокой производительности во время исполнения программы;
Библиотека CImg имеет следующую структуру:
- все классы и функции библиотеки определены в пространстве имен cimg_library, которое инкапсулирует в себе всю функциональность библиотеки и позволяет избежать коллизий, которые могут случится при добавлении других заголовочных файлов в проект. Обычно используют только это пространство имен как стандартное:
#include "CImg.h" using namespace cimg_library;
- Пространство имен cimg_library::cimg определяет набор низкоуровневых функций и переменных, используемых в библиотеке;
- Класс cimg_library::CImg<T> — основной класс библиотеки, экземпляры которого представляют сущность (изображение) вплоть до 4-х размерного (начиная от одноразмерного скаляра до 3-х мерных наборов пикселей), с шаблонными типами пикселей;
- Класс cimg_library::CImgList<T> представляет списки cimg_library::CImg изображений. Он может быть использован, например, для хранения последовательности изображений (кадров, ...);
Класс cimg_library::CImgDisplay отображает изображения или наборы изображений в графической среде. Можно смело заявить, что код этого класса сильно зависит от системы, но на самом деле это не волнует программиста, т.к. переменные среды устанавливаются автоматически посредством CImg-библиотеки;
Класс cimg_library::CImgException (и его подклассы) используются библиотекой для обработки исключений при возникновении ошибок. Исключения обрабатываются с помощью try {..} catch (CImgException) {… }. Подклассы позволяют точно определить тип ошибки;Знание этих четырех классов достаточно, чтобы в полное мере пользоваться функциональностью CImg-библиотеки.
Hello, world!
Ну да ладно, сказано было достаточно много. Рассмотрим лучше наглядный пример того, как работает элементарная программа, написанная с использованием CImg.
#include "CImg.h" using namespace cimg_library; int main() { CImg<unsigned char> img(640,400,1,3); img.fill(0); unsigned char purple[] = { 255,0,255 }; img.draw_text(100,100,"Hello World",purple); img.display("My first CImg code"); return 0; }
Рассмотрим более детально каждую строку программы:
Подключим заголовочный файл библиотеки CImg
#include "CImg.h"
Будем использовать пространство имен cimg_library, чтобы облегчить объявления типов
using namespace cimg_library;
Объявим главную функцию программы
int main() {
Создадим экземпляр изображения — img, с типом пикселей unsigned char, размера 640*400*1 пикселей (в данном случае 1 говорит о том, что изображение будет плоским, не трехмерным). Каждый пиксель имеет 3 канала — RED, GREEN и BLUE. Об этом говорит последний параметр конструктора.
CImg<unsigned char> img(640,400,1,3);
Закрасим изображение черным цветом («0» означает черный)
img.fill(0);
Объявим переменную purple: она будет цветом
unsigned char purple[] = { 255,0,255 };
Выведем от точки (100,100) на изображении текст «Hello World» цветом purple
img.draw_text(100,100,"Hello World",purple);
Покажем изображение в графическом окне с заголовком «My first CImg code»
img.display("My first CImg code");
Завершим программу
return 0;
Как видно, библиотека CImg достаточна проста в использовании, названия методов интуитивно понятны. Хотя вышеизложенный код можно было записать еще более компактно:
#include "CImg.h" using namespace cimg_library; int main() { const unsigned char purple[] = { 255,0,255 }; CImg<unsigned char>(640,400,1,3,0).draw_text(100,100,"Hello World",purple).display("My first CImg code"); return 0; }
Скриншот (кликабельно):
Надеюсь, в будущем разберем еще несколько примеров, уже посложнее!
Сайт проекта: cimg.sourceforge.net
Благодарю за внимание!
P.S.- В Linux компилируется командой:
g++ -o hello hello.cpp -O2 -L/usr/X11R6/lib -lm -lpthread -lX11
(Можно обойтись и без -O2) - Компилируется достаточно долго (Linux Gentoo, Pentium® Dual-Core CPU T4500 @ 2.30GHz):
$ time g++ -o hello hello.cpp -O2 -L/usr/X11R6/lib -lm -lpthread -lX11
real 0m28.397s
user 0m27.991s
sys 0m0.265s
28 секунд (!) для Hello, World! не слишком ли? Хотя без "-O2" быстрее в три раза. - Размер бинарника составляет 742K что, в общем сопоставимо со временем компиляции!
- В Linux компилируется командой:
Автор: alexeyanikanov