Чтение онлайн

на главную

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

Фигуры изображаются одна поверх другой, подобно листам бумаги, в порядке их добавления на экран. По этой причине объект

path
оказался на самом “дне”, просто потому, что он был связан с окном до объекта
rita
. Изображения могут кодироваться во множестве форматов. Здесь мы используем только два из них: JPEG и GIF.

struct Suffix {

enum Encoding { none, jpg, gif };

};

В

нашей библиотеке графического интерфейса изображение в памяти представляется как объект класса
Image
.

struct Image:Shape {

Image(Point xy, string file_name,

Suffix::Encoding e = Suffix::none);

~Image { delete p; }

void draw_lines const;

void set_mask(Point xy, int ww, int hh)

{ w=ww; h=hh; cx=xy.x; cy=xy.y; }

private:

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
и связывается с указателем. Подробности его реализации (в главе 17 рассматривается оператор new и указатели) связаны с организацией библиотеки FLTK и не имеют для нас большого значения.

Теперь настало время реализовать функцию

can_open
, проверяющую, можно ли открыть файл для чтения.

bool can_open(const string& s)

// проверка, существует ли файл s и можно ли его открыть

// для чтения

{

ifstream ff(s.c_str);

return ff;

}

Открыть файл, а затем закрыть его, — довольно примитивный способ проверки, позволяющий отделить ошибки, связанные с невозможностью открыть файл, от ошибок, обусловленных неприемлемым форматированием данных.

Если хотите, можете посмотреть на определение функции

get_encoding
: она просто анализирует суффикс и ищет соответствие в таблице заранее заданных суффиксов. Эта таблица реализована с помощью стандартного типа
map
(подробнее об этом — в разделе 21.6).

Задание

1. Создайте объект класса

Simple_window
размером 800x1000 пикселей.

2. Разместите сетку размером 8?8 пикселей в левой части окна размером 800 на 800 пикселей (так что каждый квадрат сетки имеет размер 100x100 пикселей).

3. Создайте восемь красных квадратов, расположенных по диагонали, начиная с левого верхнего угла (используйте класс

Rectangle
).

4. Подберите изображение размером 200x200 пикселей (в формате JPEG или GIF) и разместите три его копии поверх сетки (каждое изображение покроет четыре квадрата). Если вы не найдете изображения, размеры которого точно равнялись бы 200 пикселям, то, используя функцию

set_mask
, вырежьте соответствующий фрагмент более крупного изображения. Не закрывайте красные квадраты.

Поделиться:
Популярные книги

Кодекс Крови. Книга VIII

Борзых М.
8. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VIII

Камень

Минин Станислав
1. Камень
Фантастика:
боевая фантастика
6.80
рейтинг книги
Камень

Партиец

Семин Никита
2. Переломный век
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Партиец

Он тебя не любит(?)

Тоцка Тала
Любовные романы:
современные любовные романы
7.46
рейтинг книги
Он тебя не любит(?)

Бестужев. Служба Государевой Безопасности

Измайлов Сергей
1. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности

Хозяйка брачного агентства или Попаданка в поисках любви

Максонова Мария
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Хозяйка брачного агентства или Попаданка в поисках любви

Возрождение Феникса. Том 1

Володин Григорий Григорьевич
1. Возрождение Феникса
Фантастика:
фэнтези
попаданцы
альтернативная история
6.79
рейтинг книги
Возрождение Феникса. Том 1

Релокант. Вестник

Ascold Flow
2. Релокант в другой мир
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Релокант. Вестник

Книга пяти колец. Том 3

Зайцев Константин
3. Книга пяти колец
Фантастика:
фэнтези
попаданцы
аниме
5.75
рейтинг книги
Книга пяти колец. Том 3

Идеальный мир для Лекаря 8

Сапфир Олег
8. Лекарь
Фантастика:
юмористическое фэнтези
аниме
7.00
рейтинг книги
Идеальный мир для Лекаря 8

Идеальный мир для Социопата 6

Сапфир Олег
6. Социопат
Фантастика:
боевая фантастика
рпг
6.38
рейтинг книги
Идеальный мир для Социопата 6

Камень. Книга 3

Минин Станислав
3. Камень
Фантастика:
фэнтези
боевая фантастика
8.58
рейтинг книги
Камень. Книга 3

Прометей: повелитель стали

Рави Ивар
3. Прометей
Фантастика:
фэнтези
7.05
рейтинг книги
Прометей: повелитель стали

Неудержимый. Книга XIX

Боярский Андрей
19. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XIX