int w,h; // определяем "маскировочное окно" внутри изображения
// по отношению к позиции (cx,cy)
int cx,cy;
Fl_Image* p;
Text fn;
};
Конструктор класса Image
Image
выводит на экран объект Bad_image
. Определение класса Bad_image
выглядит так:struct Bad_image:Fl_Image {
Bad_image(int h, int w):Fl_Image(h,w,0) { }
void draw(int x,int y, int, int, int, int) { draw_empty(x,y);
}
};
Работа с изображениями в графической библиотеке довольно сложна, но основная сложность класса Image
// более сложный конструктор, потому что ошибки,
// связанные с графическими файлами, трудно найти
Image::Image(Point xy, string s, Suffix::Encoding e)
:w(0), h(0), fn(xy,"")
{
add(xy);
if (!can_open(s)) { // можно ли открыть файл s?
fn.set_label("Невозможно открыть \""+s+" ");
p = new Bad_image(30,20); // ошибка графики
return;
}
if (e == Suffix::none) e = get_encoding(s);
switch(e) { // проверка кодировки
case Suffix::jpg:
p = new Fl_JPEG_Image(s.c_str());
break;
case Suffix::gif:
p = new Fl_GIF_Image(s.c_str());
break;
default: // неприемлемая кодировка
fn.set_label("Неприемлемый тип файла \""+s+" ");
p = new Bad_image(30,20); // ошибка графики
}
}
Расширение файла используется для того, чтобы определить вид объекта, создаваемого для хранения изображения ( Fl_JPEG_Image или Fl_GIF_Image). Этот объект создается с помощью оператора new
Теперь настало время реализовать функцию can_open()
bool can_open(const string& s)
// проверка, существует ли файл s и можно ли его открыть
// для чтения
{
ifstream ff(s.c_str());
return ff;
}
Открыть файл, а затем закрыть его, — довольно примитивный способ проверки, позволяющий отделить ошибки, связанные с невозможностью открыть файл, от ошибок, обусловленных неприемлемым форматированием данных.
Если хотите, можете посмотреть на определение функции get_encoding()
map
(подробнее об этом — в разделе 21.6).Задание
1. Создайте объект класса Simple_window
2. Разместите сетку размером 88 пикселей в левой части окна размером 800 на 800 пикселей (так что каждый квадрат сетки имеет размер 100×100 пикселей).
3. Создайте восемь красных квадратов, расположенных по диагонали, начиная с левого верхнего угла (используйте класс Rectangle
4. Подберите изображение размером 200×200 пикселей (в формате JPEG или GIF) и разместите три его копии поверх сетки (каждое изображение покроет четыре квадрата). Если вы не найдете изображения, размеры которого точно равнялись бы 200 пикселям, то, используя функцию set_mask()
5. Добавьте изображение размером 100×100 пикселей. Перемещайте его с одного квадрата на другой, щелкая на кнопке Next
. Для этого поместите вызов функцииwait_for_button()
в цикл, сопроводив его командами, выбирающими новый квадрат для вашего изображения.Контрольные вопросы
1. Почему мы просто не используем какую-нибудь коммерческую или бесплатную графическую библиотеку?
2. Сколько классов из библиотеки графического интерфейса нам понадобится, чтобы создать простой вывод графической информации?