Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

13.17. Класс Image

Файлы в типичном персональном компьютере хранят тысячи изображений. Кроме того, миллионы изображений доступны в сети веб. Естественно, мы хотели бы отображать содержимое этих файлов на экране с помощью относительно простых программ. Например, ниже продемонстрирован рисунок (

rita_path.gif
), иллюстрирующий путь урагана “Рита”, пришедшего из Мексиканского залива.

Мы можем выбрать часть этого изображения и добавить фотографию урагана, сделанную из космоса (

rita.jpg
).

Image rita(Point(0,0),"rita.jpg");

Image path(Point(0,0),"rita_path.gif");

path.set_mask(Point(50,250),600,400); // выбираем желательную область

win.attach(path);

win.attach(rita);

Операция

set_mask
выбирает часть рисунка, которую следует изобразить на экране. В данном случае мы выбрали изображение размером 600x400 пикселей из файла
rita_path.gif
(загруженный как объект
path
) и показали его в области, левый верхний угол которой имеет координаты (50,250). Выбор части рисунка — довольно распространенный прием, поэтому мы предусмотрели для него отдельную операцию.

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

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+" ");

  • Читать дальше
  • 1
  • ...
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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