Работа с изображениями c Перевод сделан Александром Анатольевичем



Скачать 321.59 Kb.

Дата16.12.2016
Размер321.59 Kb.
Просмотров196
Скачиваний0
ТипГлава

Глава
10
Работа с изображениями c Перевод сделан Александром Анатольевичем
В главе рассматривается работа с растровыми изображениями. Изображения очень важны для вашего приложения и могут использоваться с элементами управле- ния, например, с панелями инструментов, списками, вкладками, кнопками, HTML- окнами или при рисовании. Иногда их можно сделать невидимыми в приложении,
например, когда необходимо избежать мерцания во время перерисовки. В данной гла- ве мы рассмотрим различные классы изображений и методы изменения стандартных иконок и изображений, используемых в wxWidgets.
10.1
Классы изображений в wxWidgets
Библиотека wxWidgets поддерживает четыре типа растровых изображений:
wxBitmap, wxIcon, wxCursor и wxImage.
wxBitmap представляет изображение в платформозависимом виде с необязатель- ным объектом wxMask, который может хранить прозрачность. В системе Windows класс wxBitmap реализован с использованием аппаратно-независимого типа растро- вого отображения (device-independent bitmap, DIB). Для систем GTK+ и X11 каж- дый wxBitmap содержит битовую карту для GDK и X11 соответственно. В системе
Mac используется тип PICT. Объекты класса wxBitmap можно легко преобразовать в/из wxImage.
wxIcon — это платформозависимая концепция иконки, маленького изображения с прозрачностью, которое используют, чтобы некоторые фреймы или диалоги имели отличительный значок. На платформах GTK+, X11 и Mac иконка является обычным изображением, которое всегда имеет wxMask. В системе Windows иконки представля- ются в виде специальных объектов — HICON.
wxCursor представляет изображение указателя мыши: GdkCursor на GTK+,
Cursor на X11, HCURSOR в Windows и Cursor на платформе Mac. Каждый курсор имеет «активную точку» (пиксель в изображении курсора, который является точ- ным положением указателя мыши), а также маску.
Только wxImage из этих четырех классов имеет платформонезависимую ре- ализацию, поддерживающую 24-битные изображения с альфа-каналом. Объек- ты данного класса можно создать из бинарных данных или используя метод
1

2
Глава 10. Работа с изображениями wxBitmap::ConvertToImage. wxImage может быть загружен из файлов, записанных в различных форматах. А также можно добавить поддержку любых других форматов через использование обработчиков формата. В отличие от wxBitmap, объекты класса wxImage нельзя рисовать непосредственно на wxDC. Вместо этого вы должны создать wxBitmap из вашего wxImage, а после чего полученный объект нарисовать на кон- тексте устройства используя метод wxDC::DrawBitmap. wxImage поддерживает маску для индикации цвета и альфа-канал, которые вместе позволяют строить достаточно сложные примеры прозрачности.
Вы можете проводить преобразования между перечисленными типами растровых изображений, однако в различных ОС существуют некоторые ограничения на полу- чаемый результатах.
Заметим, что все классы растровых изображений содержат счетчик ссылок, по- этому операции присваивания и копирования для них дешевы, потому что не проис- ходит реального копирования данных. Однако, вы должны понимать, что изменения одного изображения приведет к тому, что изменятся все объекты ссылающийся на те же данные.
Все классы изображений используют стандартный идентификатор wxBitmapType для загрузки и сохранения данных. Возможные значения данного типа указаны в таблице
10.1
Таблица 10.1: Типы изображений
Тип
Описание wxBITMAP_TYPE_BMP
Растровое изображение в
Windows (BMP).
wxBITMAP_TYPE_BMP_RESOURCE
Растровое изображение в
Windows, загруженное из ре- сурсной части выполняемого файла.
wxBITMAP_TYPE_ICO
Иконка в
системе
Windows
(ICO).
wxBITMAP_TYPE_ICO_RESOURCE
Иконка в системе Windows, за- груженная из ресурсной части выполняемого файла.
wxBITMAP_TYPE_CUR
Курсор в
системе
Windows
(CUR).
wxBITMAP_TYPE_CUR_RESOURCE
Курсор в системе Windows, за- груженный из ресурсной части выполняемого файла.
wxBITMAP_TYPE_XBM
Монохромное изображение
XBM, загруженное в системе
Unix.
wxBITMAP_TYPE_XBM_DATA
Монохромное изображение
XBM, построенное из данных
C++.
2

10.1. Классы изображений в wxWidgets
3
Таблица 10.1: Типы изображений (продолжение)
Тип
Описание wxBITMAP_TYPE_XPM
Цветное изображение из XPM- файла (хороший кроссплатфор- менный формат для маленьких изображений, который может быть вкомпилирован в приложе- ние).
wxBITMAP_TYPE_XPM_DATA
Цветное изображение XPM, по- строенное из данных C++.
wxBITMAP_TYPE_TIF
Изображение из TIFF-файла,
популярен для больших изобра- жений.
wxBITMAP_TYPE_GIF
Изображение из
GIF-фай- ла, максимум 256 цветов и,
возможно,
информация о
прозрачности.
wxBITMAP_TYPE_PNG
Изображение из
PNG-файла
(популярный формат с прозрач- ностью и альфа-каналом, сво- бодный от проблем с патента- ми).
wxBITMAP_TYPE_JPEG
Изображение из JPEG-файла
(популярный формат сжатия для больших изображений, но производит его с потерями, по- этому не пригоден для много- кратных сжатий/распаковок).
wxBITMAP_TYPE_PCX
Изображение из PCX-файла.
wxBITMAP_TYPE_PICT
Изображение из PICT-файла в системе Mac.
wxBITMAP_TYPE_PICT_RESOURCE
Изображение из PICT-файла в системе Mac, загруженное из ресурсной части выполняемого файла.
wxBITMAP_TYPE_ICON_RESOURCE
В системе Mac OS X загружа- ет стандартную иконку (такую как wxICON_INFORMATION) или ресурс с иконкой.
wxBITMAP_TYPE_ANI
Анимированная иконка в систе- ме Windows (ANI).
wxBITMAP_TYPE_IFF
Изображение из IFF-файла.
wxBITMAP_TYPE_MACCURSOR
Курсор в системе Mac.
wxBITMAP_TYPE_MACCURSOR_RESOURCE
Курсор в системе Mac, загру- женный из ресурсной части вы- полняемого файла.
3

4
Глава 10. Работа с изображениями
Таблица 10.1: Типы изображений (продолжение)
Тип
Описание wxBITMAP_TYPE_ANY
Указывает коду загрузки изоб- ражения выяснять тип непо- средственно во время чтения.
10.2
Работа с wxBitmap
С помощью wxBitmap Вы можете сделать несколько вещей:
• Рисовать его в окне с помощью контекста устройства.
• Использовать его в
качестве изображения для таких классов,
как wxBitmapButton, wxStaticBitmap или wxToolBar.
• Использовать его для рисования методом двойной буферизации (рисования в невидимом буфере wxMemoryDC, который, в свою очередь, и будет рисоваться в окне).
На некоторых платформах (в частности в Windows) на количество растровых изображений накладывается ограничение, поэтому если у вас много изображений,
которые необходимо хранить в памяти, то предпочтительней работать с объектами класса wxImage и конвертировать их во временный wxBitmap для рисования в кон- тексте устройства.
Перед тем, как мы обсудим создание объекта wxBitmap и рисование с его помо- щью, давайте рассмотрим методы этого класса (таблица
10.2
).
Таблица 10.2: Методы wxBitmap
Метод
Описание wxBitmap
Растровое изображение может быть создано с помощью задания высоты и ширины, из друго- го растрового изображения, из wxImage, данных
XPM (char**), битовых данных (char[]) или из файла (с указанием имени файла и его типа).
ConvertToImage
Конвертирует в wxImage с сохранением прозрач- ности.
CopyFromIcon
Создает растровое изображение из wxIcon.
Create
Создает растровое изображение заданного раз- мера или из указанных данных.
GetWidth, GetHeight
Возвращает размеры растрового изображения.
GetDepth
Возвращает глубину цвета изображения.
GetMask, SetMask
Возвращает объект класса wxMask или NULL.
GetSubBitmap
Возвращает область текущего изображения в качестве нового растрового изображения.
LoadFile, SaveFile
Для загрузки изображения из файла и сохране- ния в файл (поддерживается множество форма- тов).
4

10.2. Работа с wxBitmap
5
Таблица 10.2: Методы wxBitmap (продолжение)
Метод
Описание
Ok
Возвращает true, если объект содержит реаль- ные данные.
10.2.1
Создание wxBitmap
Существует несколько способов создания объекта класса wxBitmap.
Вы можете создать неинициализированный объект (без данных изображения),
используя конструктор по умолчанию. После этого вам необходимо вызвать Create,
LoadFile или назначить объекту существующее растровое изображение для того,
чтобы с ним работать.
Вы можете создать wxBitmap, задав ему размер и глубину. Созданное растро- вое изображение будет заполнено произвольными данными, поэтому необходимо на нем что-нибудь нарисовать. Далее показан пример создания изображения размером
200x100 пикселей и заливки его белым цветом.
// Создает изображение размером 200x100 пикселей с текущей глубиной дисплея wxBitmap bitmap(200, 100,
-1);
// Создаем контекст устройства в памяти (memory device context)
wxMemoryDC dc;
// Назначаем контексту устройства наше изображение dc.SelectObject(bitmap);
// Задаем белый фон dc.SetBackground(*wxWHITE_BRUSH);
// Закрашиваем изображение белым (очищаем)
dc.Clear();
// Отсоединяем изображение от контекста dc.SelectObject(wxNullBitmap);
Вы можете создать растровое изображение из любой картинки, сохранив при этом маску или альфа-канал исходного изображения:
// Загружаем картинку из файла wxImage image(wxT("image.png"), wxBITMAP_TYPE_PNG);
// Конвертируем в растровое изображение wxBitmap bitmap(image);
Растровое изображение также можно создать из иконки, используя метод
CopyFromIcon:
5

6
Глава 10. Работа с изображениями
// Загружаем иконку wxIcon icon(wxT("image.xpm"), wxBITMAP_TYPE_XPM);
// Конвертируем иконку в растровое изображение wxBitmap bitmap;
bitmap.CopyFromIcon(icon);
Или же можно загрузить изображение из файла:
// Загружаем из файла wxBitmap bitmap(wxT("picture.png", wxBITMAP_TYPE_PNG);
if (!bitmap.Ok())
{
wxMessageBox(wxT("Sorry, could not load file."));
}
Класс wxBitmap может загружать все типы файлов, которые может загружать wxImage (смотрите таблицу
10.3
), используя wxImage или более эффективную реали- зацию для некоторых типов файлов для конкретной платформы. wxWidgets поддер- живает наиболее популярные форматы PNG, JPEG, TIFF, BMP и XPM, загрузка и сохранение которых поддерживается на всех платформах.
Таблица 10.3: Доступные обработчики форматов изоб- ражений
Имя
Описание wxBMPHandler
Для загрузки и сохранения Windows файлов растровых изображений (с расширением BMP).
wxPNGHandler
Для загрузки и сохранения PNG-файлов. Под- держиваются изображения с прозрачностью и альфа-каналом.
wxJPEGHandler
Для загрузки и сохранения JPEG-файлов.
wxGIFHandler
GIF файлы: из-за лицензионных ограничений доступна только загрузка.
wxPCXHandler
Для загрузки и
сохранения
PCX-файлов.
wxPCXHandler подсчитывает количество цветов в изображении: если в изображении 256 или меньше, то оно будет сохранено в 8-битном фор- мате; в противном случае в 24-битном.
wxPNMHandler
Для загрузки и сохранения PNM-файлов. За- грузка файлов PNM работает только для ASCII
или строковых RGB-изображений. При сохране- нии в PNM-формате, wxPNMHasndler всегда со- храняет в строковом RGB.
wxTIFFHandler
Для загрузки и сохранения TIFF-файлов.
wxIFFHandler
Для загрузки IFF-файлов.
wxXPMHandler
Для загрузки и сохранения XPM-файлов.
wxICOHandler
Для загрузки и сохранения иконок Windows.
6

10.2. Работа с wxBitmap
7
Таблица 10.3: Доступные обработчики форматов изоб- ражений (продолжение)
Имя
Описание wxCURHandler
Для загрузки и сохранения файлов курсора
Windows.
wxANIHandler
Для загрузки и сохранения анимированных кур- соров Windows.
Также можно загрузить ресурсы формата PICT в системе Mac OS X, указав спе- циальный тип wxBITMAP_TYPE_PICT_RESOURCE. Если вы хотите загрузить специфи- ческие ресурсы для данной платформы, то можете использовать макрос wxBITMAP.
Например:
#if !defined(__WXMSW__) && !defined(__WXPM__)
#include "picture.xpm"
#endif wxBitmap bitmap(wxBITMAP(picture));
На Windows и OS/2 этот код будет загружать ресурс picture из исполняемого файла, а на всех других платформах он будет загружать переменную picture_xpm из XPM-файла. В любом случае формат XPM поддерживается всеми платформами,
поэтому в общем случае необходимости в данном макросе нет.
10.2.2
Использование wxMask
Каждый объект wxBitmap может иметь маску (wxMask) — монохромное изобра- жение, которое указывает прозрачные области основного растрового изображения.
Маска создается автоматически, когда вы загружаете изображение с прозрачностью
(например, изображения XPM, PNG или GIF), но Вы можете создать его программно и назначить методом SetMask. wxMask можно создать из wxBitmap или из wxBitmap,
с указанием цвета, который будет обозначать прозрачную область.
Следующий пример создает монохромное прозрачное изображение mainBitmap шириной и высотой в 32 пикселя из растрового изображения (imageBits) и маски
(maskBits). В изображении установленный бит обозначает черный цвет, а нулевой —
белый. Для маски установленный бит указывает на непрозрачность, а нулевой — на прозрачность.
static char imageBits[] = { 255, 255, 255, 255, 31,
255, 255, 255, 31, 255, 255, 255, 31, 255, 255, 255,
31, 255, 255, 255, 31, 255, 255, 255, 31, 255, 255,
255, 31, 255, 255, 255, 31, 255, 255, 255, 25, 243,
255, 255, 19, 249, 255, 255, 7, 252, 255, 255, 15, 254,
255, 255, 31, 255, 255, 255, 191, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
7

8
Глава 10. Работа с изображениями
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255 };
static char maskBits[] = { 240, 1, 0, 0, 240, 1,
0, 0, 240, 1, 0, 0, 240, 1, 0, 0, 240, 1, 0, 0, 240, 1,
0, 0, 240, 1, 0, 0, 240, 1, 0, 0, 255, 31, 0, 0, 255,
31, 0, 0, 254, 15, 0, 0, 252, 7, 0, 0, 248, 3, 0, 0,
240, 1, 0, 0, 224, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0 };
wxBitmap mainBitmap(imageBits, 32, 32);
wxBitmap maskBitmap(maskBits, 32, 32);
mainBitmap.SetMask(new wxMask(maskBitmap));
10.2.3
Формат XPM
Если Вам нужны небольшие растровые изображения с прозрачностью, например для кнопок на панели инструментов или для изображений на вкладках и списках, то удобнее всего использовать формат XPM. Преимущество этого формата в том, что он использует C/C++ синтаксис и таким образом он может подгружаться динамически или быть вкомпилированным в вашу программу. Например:
// Также можно использовать #include "open.xpm"
static char *open_xpm[] = {
/* columns rows colors chars-per-pixel */
"16 15 5 1",
"
c None",
". c Black",
"X c Yellow",
"o c Gray100",
"O c #bfbf00",
/* pixels */
"
",
"
",
"
. .",
"
..",
"
...",
" .XoX.......
",
" .oXoXoXoXo.
",
" .XoXoXoXoX.
",
" .oXoX..........",
8

10.2. Работа с wxBitmap
9
" .XoX.OOOOOOOOO.",
" .oo.OOOOOOOOO. ",
" .X.OOOOOOOOO.
",
" ..OOOOOOOOO.
",
" ...........
",
"
"
};
wxBitmap bitmap(open_xpm);
Как вы видите, XPM файлы состоят из символьных данных. Перед данными собственно изображения, записана палитра, где каждому символу привязывается определенный цвет с использованием встроенного идентификатора цвета или шести- разрядным числом в шестнадцатеричном формате, перед которым ставится символ
«#». Идентификатор None указывает на прозрачную область изображения. Формат
XPM не популярен в графических редакторах под Windows, но вы можете сохранить изображение как PNG и сконвертировать его в XPM (например, с помощью редакто- ра ImageBlocks, который поставляется с DialogBlocks, или попробуйте сами написать на wxWidgets небольшой конвертер).
10.2.4
Рисование растровых изображений
Растровое изображение можно нарисовать двумя различными способами. Вы можете ассоциировать (назначить) изображение контексту устройства памяти
(wxMemoryDC), а потом использовать wxDC::Blit для того, что бы перенести содержи- мое растрового изображения в другой контекст устройства. Или же можно просто использовать метод wxDC::DrawBitmap. В обоих случаях, если изображение имеет прозрачность или альфа-канал, то вы должны указать это, передав true в метод.
В следующем примере использованы оба метода:
// Рисование растрового изображения с wxMemoryDC
wxMemoryDC memDC;
memDC.SelectObject(bitmap);
// Рисуем в координатах 100, 100 на конечном контексте устройства destDC.Blit(100, 100,
// Рисуем в (100, 100)
bitmap.GetWidth(), bitmap.GetHeight(),
// Рисуем все изображение
& memDC,
// Из memDC
0, 0,
// С начала координат изображения wxCOPY,
// Логическая операция true);
// Изображение содержит маску memDC.SelectObject(wxNullBitmap);
// Альтернативный способ: используем DrawBitmap destDC.DrawBitmap(bitmap, 100, 100, true);
Более детально рисование растровых изображений описывается в Главе 5 «Рисо- вание и печать».
9

10
Глава 10. Работа с изображениями
10.2.5
Упаковка графических ресурсов
Если Вы программировали под Windows, то привыкли загружать растровые изоб- ражения из ресурсов исполняемых файлов. Вы можете не изменять своей привычке и загружать их из ресурсов, используя wxBITMAP_TYPE_BMP_RESOURCE в конструкторе,
но скорее всего Вы предпочтете менее платформозависимый метод.
Очень удобный способ хранить ресурсы приложения, будь то растровые изображе- ния, HTML-файлы или другие файлы — это хранить их в одном zip-архиве, отдель- но от исполняемого файла, или в отдельной каталоге с данными. Также вы можете использовать функциональность виртуальных файловых систем wxWidgets, чтобы загружать изображение прямо из zip-архива, как показано в следующем примере:
// Создадим новый объект файловой системы wxFileSystem*fileSystem = new wxFileSystem;
wxString archiveURL(wxT("myapp.bin"));
wxString filename(wxT("myimage.png"));
wxBitmapType bitmapType = wxBITMAP_TYPE_PNG;
// Создаем URL
wxString combinedURL(archiveURL + wxString(wxT("#zip:")) + filename);
wxImage image;
wxBitmap bitmap;
// Открываем архив wxFSFile* file = fileSystem->OpenFile(combinedURL);
if (file)
{
wxInputStream* stream = file->GetStream();
// Load and convert to a bitmap if (image.LoadFile(* stream, bitmapType))
bitmap = wxBitmap(image);
delete file;
}
delete fileSystem;
if (bitmap.Ok())
{
}
Более подробно о виртуальных файловых системах, вы сможете узнать в Главе 14
«Файлы и потоки».
10

10.3. Работа с wxIcon
11 10.3
Работа с wxIcon wxIcon — это небольшое растровое изображение у которого всегда есть маска.
wxIcon можно использовать:
• Как иконку для фрейма или диалога;
• Как иконку для wxTreeCtrl, wxListCtrl или wxNotebook через класс wxImageList (подробности далее в этой главе);
• Рисовать иконку в контексте устройства, используя wxDC::DrawIcon.
Таблица
10.4
содержит основные методы класса иконок.
Таблица 10.4: Методы wxIcon
Метод
Описание wxIcon
Иконка может быть создана с использованием другой иконки, данных XPM (char**), битовых данных (char[]) или из файла с заданным фор- матом.
CopyFromBitmap
Создает иконку из wxBitmap.
GetWidth, GetHeight
Возвращает размер иконки.
GetDepth
Возвращает глубину цвета иконки.
LoadFile
Загружает иконку из файла.
Ok
Возвращает true, если объект содержит реаль- ные данные.
10.3.1
Создание wxIcon
Объект wxIcon можно создать, используя XPM-данные, вкомпиленные в прило- жение, из объекта wxBitmap, из битовых данных или загрузить из файла, напри- мер из XPM-файла с прозрачностью. В wxWidgets есть макрос wxICON, аналогичный wxBITMAP (рассмотренному выше) для загрузки из ресурса, характерного для данной платформы, либо из XPM-данных.
В Windows метод LoadFile и схожий с ним конструктор будет работать для раст- ровых изображений Windows (BMP) и иконок (ICO), ресурсов и файлов. Если Вы хотите работать с другим форматом, загрузите файл в wxBitmap и сконвертируйте в иконку.
На Mac OS X и Unix/Linux с использованием GTK+, wxIcon имеет те же возмож- ности при загрузке из файла, что и wxBitmap.
В следующем примере показано создание объекта wxIcon различными способами.
// Метод 1: загрузка из XPM-данных
#include "icon1.xpm"
wxIcon icon1(icon1_xpm);
// Метод 2: загрузка из ICO-ресурса (только для Window и OS/2)
wxIcon icon2(wxT("icon2"));
11

12
Глава 10. Работа с изображениями
// Метод 3: загрузка из ICO-файла (только для Window и OS/2)
// Вы можете указать желаемый размер, так как файл
// может содержать несколько иконок.
wxIcon icon3(wxT("icon3.ico"), wxBITMAP_TYPE_ICO, 16, 16);
// Метод 4: создание из растрового изображения wxIcon icon4;
wxBitmap bitmap(wxT("icon4.png"), wxBITMAP_TYPE_PNG);
icon4.CopyFromBitmap(bitmap);
10.3.2
Использование wxIcon
В следующем фрагменте показаны три различных способа использования wxIcon:
установка иконки фрейма, добавление в список изображений и рисование в контексте устройства.
#include "myicon.xpm"
wxIcon icon(myicon_xpm);
// 1: Установка иконкой фрейма frame->SetIcon(icon);
// 2: Добавление в wxImageList wxImageList* imageList = new wxImageList(16, 16);
imageList->Add(icon);
// 3: Рисование иконки в точке (10, 10)
wxClientDC dc(window);
dc.DrawIcon(icon, 10, 10);
10.3.3
Назначение иконки приложению
Назначить иконку приложению (чтобы операционная система использовала ее как значок приложения), нельзя с помощью инструментов wxWidgets и это одно из немногих мест, где вы должны использовать свой особый способ для каждой из платформ.
В Windows необходимо добавить скрипт для ресурсов (файл с расширением .rc)
в ваш makefile или в файл проекта, а также добавить выражение ICON в файл .rc,
например:
aardvarkpro ICON aardvarkpro.ico
#include "wx/msw/wx.rc"
Здесь, aardvarkpro.ico — это имя файла c иконкой с разным размером и глубиной цвета (обычно используют размеры 48x48, 32x32 и 16x16). Когда запускаемый файл показывается в Проводнике (Windows Explorer) Windows просматривает иконки из
12

10.4. Работа с wxCursor
13
ресурса в алфавитном порядке, таким образом, если в ресурсе у вас несколько ико- нок, удостоверьтесь, что нужная иконка приложения в алфавитном порядке первая в списке; иначе на рабочем столе или в каталоге будет не та иконка, которую вы ожидали увидеть.
В системе Mac вам необходимо подготовить пакет (bundle) для приложения, ко- торый будет содержать несколько ICNS-файлов. Дополнительную информацию о пакетах вы можете найти в разделе об установке в Главе 20 «Сделаем ваше прило- жение идеальным». Нужная секция файла в пакете Info.plist, например, может выглядеть вот так:
CFBundleDocumentTypes


CFBundleTypeExtensions

pjd

CFBundleTypeIconFile
dialogblocks-doc.icns
CFBundleTypeName
pjdfile
CFBundleTypeRole
Editor


CFBundleIconFile
dialogblocks-app.icns
Иконки для вашего приложения и документов вашего приложения описываются в свойствах CFBundleIconFile и CFBundleTypeIconFile. Вы можете создать ICNS- файл с помощью редактора иконок, которые поставляется компанией Apple. Если вы преимущественно работаете в другой операционной системе, то необходимо создать несколько иконок с разрешением 16x16, 32x32, 48x48 и 128x128, сохранить их в фор- мате PNG, скопировать их на Mac, а потом скопировать их и вставить в нужном месте в редактор иконок. Удостоверьтесь, что каждый PNG-файл содержит маску,
которую редактор будет использовать при создании иконки.
В системе Linux пользовательские среды GNOME и KDE имеют свои способы для назначения иконок приложениям, которые коротко будут описаны в Главе 20.
10.4
Работа с wxCursor
Курсор используется для указания позиции указателя мыши на экране. Вы мо- жете изменить курсор для отдельного окна, если хотите акцентировать внимание пользователя на конкретной функции мыши в данном окне. Так же как и иконки,
13

14
Глава 10. Работа с изображениями курсор — это небольшое изображение с поддержкой прозрачности. Создать его мож- но с помощью как общих, так и с помощью специфического для данной платформы конструктора. Некоторые из этих конструкторов берут актуальную позицию указа- теля как самую левую верхнюю точку изображения курсора, и именно эта точка по умолчанию является «острием» вашего курсора.
Таблица 10.5: Методы wxCursor
Имя
Описание wxCursor
Курсор может быть создан из wxImage, битовых данных (char[]), используя стандартный иден- тификатор курсора или из файла (с указанием формата файла).
Ok
Возвращает true, если объект содержит реаль- ные данные.
10.4.1
Создание wxCursor
Самый простой способ задать курсор — это передать стандартный идентификатор конструктору объекта, как показано в примере.
// Создание курсора, используя стандартный идентификатор wxCursor cursor(wxCURSOR_WAIT);
Таблица
10.6
содержит список доступных идентификаторов и их внешний вид (на различных платформах могут быть некоторые отличия).
Таблица 10.6: Идентификаторы стандартных курсо- ров
Имя
Иконка
Описание wxCURSOR_ARROW
Стандартный курсор со стрелкой.
wxCURSOR_RIGHT_ARROW
Стандартный курсор, указывающий вправо.
wxCURSOR_BLANK
Прозрачный (пустой) курсор.
wxCURSOR_BULLSEYE
Курсор с мишенью.
wxCURSOR_CROSS
Курсор с крестом.
wxCURSOR_HAND
Курсор в форме руки.
wxCURSOR_IBEAM
I-образный курсор (вертикальная линия).
wxCURSOR_LEFT_BUTTON
Изображение мыши с нажатой левой кнопкой
(только для GTK+).
wxCURSOR_MAGNIFIER
Курсор увеличения.
wxCURSOR_MIDDLE_BUTTON
Изображение мыши с нажатой средней кнопкой
(только для GTK+).
wxCURSOR_NO_ENTRY
Курсор в форме знака «входа нет».
14

10.4. Работа с wxCursor
15
Таблица 10.6: Идентификаторы стандартных курсо- ров (продолжение)
Имя
Иконка
Описание wxCURSOR_PAINT_BRUSH
Курсор в форме кисти для рисования.
wxCURSOR_PENCIL
Курсор с карандашом.
wxCURSOR_POINT_LEFT
Курсор, указывающий налево.
wxCURSOR_POINT_RIGHT
Курсор, указывающий направо.
wxCURSOR_QUESTION_ARROW
Стрелка и знак вопроса.
wxCURSOR_RIGHT_BUTTON
Изображение мыши с нажатой правой кнопкой
(только для GTK+).
wxCURSOR_SIZENESW
Курсор изменения размера в направлении СВ-
ЮЗ.
wxCURSOR_SIZENS
Курсор изменения размера в направлении С-Ю.
wxCURSOR_SIZENWSE
Курсор изменения размера в направлении СЗ-
ЮВ.
wxCURSOR_SIZEWE
Курсор изменения размера в направлении З-В.
wxCURSOR_SIZING
Курсор изменения размера (часто перемеще- ния).
wxCURSOR_SPRAYCAN
Курсор в виде кисти с пульверизатором.
wxCURSOR_WAIT
Курсор ожидания.
wxCURSOR_WATCH
Курсор в форме часов.
wxCURSOR_ARROWWAIT
Курсор со стрелкой и песочными часами.
Также можно использовать предопределенные курсоры wxSTANDARD_CURSOR,
wxHOURGLASS_CURSOR и wxCROSS_CURSOR. wxCursor можно загрузить из ресурсов соот- ветствующего типа в системе Windows и Mac OS X:
// Курсор из Windows-ресурса wxCursor cursor(wxT("cursor_resource"), wxBITMAP_TYPE_CUR_RESOURCE,
hotSpotX, hotSpotY);
// Курсор из Mac OS ресурса курсоров wxCursor cursor(wxT("cursor_resource"), wxBITMAP_TYPE_MACCUR_RESOURCE);
Вы можете создать свой курсор, используя изображение в wxImage. Актуальную позицию указателя можно задать методом wxImage::SetOptionInt, так как «острие»
курсора может в общем случае не совпадать с левой верхней точкой изображения.
Например, у курсора в виде прицела актуальная позиция находится ровно по центру изображения. Пример кода, который загружает PNG-изображение и использует его в качестве курсора:
// Создаем курсор из wxImage
15

16
Глава 10. Работа с изображениями wxImage image(wxT("cursor.png"), wxBITMAP_TYPE_PNG);
image.SetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X, 5);
image.SetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y, 5);
wxCursor cursor(image);
10.4.2
Использование wxCursor
Каждое окно может иметь свой курсор мыши, который будет использоваться,
когда мышь будет в пределах данного окна. Если для окна не указан курсор, будет использоваться курсор, заданный родительскому окну; если же у окна нет родителя с заданным курсором, то будет использован стандартный курсор.
Курсор для окна задается очень просто:
window->SetCursor(wxCursor(wxCURSOR_WAIT));
10.4.3
Использование wxSetCursorEvent
В Windows и Mac OS X есть подводные камни, которых вы должны избегать, в частности, когда вы реализуете свое собственное окно-контейнер. Например, вы ре- ализуете окно с разделителем (splitter), которое размещает свои подокна так, что видима только небольшая часть самого разделителя («ухватившись» за который пользователь сможет изменить пропорции, занимаемые дочерними окнами). Есте- ственно, для данного разделителя вы устанавливаете подходящий курсор (скажем,
wxCURSOR_WE). Таким образом, пользователь будет видеть, что границу-разделитель можно тянуть. Если при этом для дочерних окон не установлен собственный курсор,
то будет применяться курсор, установленный нашему основному окну, а в нашем случае курсор, предназначенный для разделителя.
Для того, что бы указать, что нужно использовать заданный курсор только для самого окна, а в остальных случаях рисовать стандартный, вам необходи- мо определить обработчик события wxSetCursorEvent. Это событие вызывается в
Windows и Mac OS X, когда необходимо изменить курсор (обычно, когда указа- тель мыши двигается над окном). Ваш обработчик события должен будет вызывать wxSetCursorEvent::SetCursor, чтобы изменять курсор только для данного окна:
BEGIN_EVENT_TABLE(wxSplitterWindow, wxWindow)
EVT_SET_CURSOR(wxSplitterWindow::OnSetCursor)
END_EVENT_TABLE()
// Указываем, что курсор должен изменятся только для разделителя void wxSplitterWindow::OnSetCursor(wxSetCursorEvent& event)
{
// Если мы этого не сделаем, курсор изменения размера будет использоваться
// и в дочерних окнах. Здесь мы указываем, что наш курсор
// не должен использоваться для таких окон.
if ( SashHitTest(event.GetX(), event.GetY(), 0) )
{
16

10.5. Работа с wxImage
17
// Вызываем обработчик по-умолчанию event.Skip();
}
//else: Ничего не делать, в частности не вызывать Skip()
}
В этом примере, если курсор мыши двигается над разделителем, то SashHitTest возвратит true и будет вызван метод Skip, который говорит о том, что обработку события необходимо передать следующему обработчику. Это равнозначно случаю, ко- гда мы бы вообще не написали обработку данного сообщения, а поэтому wxWidgets отображает курсор (wxCURSOR_WE), который задан для окна. Если SashHitTest воз- вратит false, то наш указатель двигается в пределах дочернего окна, а значит мы не должны заменять стандартный курсор. Если позволить завершится обработчику (не вызывая Skip) и не задавать курсор окну, то это укажет wxWidgets обрабатывать наше окно-разделитель, как не имеющее никакого установленного курсора. В итоге дочернее окно не унаследует родительский курсор, даже если дочернее окно не имеет собственного курсора (например, если дочернее окно – это wxTextCtrl, реализация которого имеет свой курсор, но wxWidgets не знает этого).
10.5
Работа с wxImage
Класс wxImage можно использовать, если вам нужен платформонезависимый класс для работы с изображениями или промежуточный класс для загрузки и сохра- нения изображения. Данный класс при хранении изображения для каждого пикселя использует по одному байту для красного, зеленого и синего компонента цвета, плюс дополнительный байт для пикселя, если изображение имеет альфа-канал.
Основные методы wxImage в приведены в таблице
10.7
Таблица 10.7: Методы wxImage
Имя
Описание wxImage
Изображение может быть создано с заданной шириной и высотой, из другого изображения,
XPM-данных, битовых данных (char[]) и оп- ционально данных об альфа-канале, из файла с указанием типа файла или из потока ввода.
ConvertAlphaToMask
Конвертирует альфа-канал (если есть) в маску.
ConvertToMono
Конвертирует в новое монохромное изображе- ние.
Copy
Возвращает идентичную копию, не используя подсчета ссылок.
Create
Создает изображение заданного размера, опци- онально инициализирует его из данных.
Destroy
Удаляет внутренние данные, если никакой дру- гой объект их не использует.
GetData, SetData
Возвращает/задает указатель на внутренние данные (unsigned char*).
17

18
Глава 10. Работа с изображениями
Таблица 10.7: Методы wxImage (продолжение)
Имя
Описание
GetImageCount
Возвращает количество изображений в файле или потоке.
GetOption,
GetOptionInt,
SetOption,
HasOption
Возвращает/задает/проверяет объект на нали- чие некоторой опции.
GetSubImage
Возвращает область изображения в качестве но- вого изображения.
GetWidth, GetHeight
Возвращают размеры изображения.
GetRed,
GetGreen,
GetBlue,
SetRGB,
GetAlpha, SetAlpha
Устанавливают или получают для пикселя зна- чения для красного, синего или зеленого компо- нента цвета или альфа-канала.
HasMask,
GetMaskRed,
GetMaskGreen,
GetMaskBlue, SetMaskColour
Методы для проверки наличия маски, установ- ки и получения цвета маски.
LoadFile, SaveFile
Загрузка из файла и сохранение изображения в файл.
Mirror
Зеркально отображает изображение в заданном направлении, результат возвращается в каче- стве нового изображения.
Ok
Возвращает true, если объект содержит реаль- ные данные.
Paste
Копирует одно изображение в другое в задан- ной точке.
Rotate, Rotate90
Вращает изображение, результат возвращается в качестве нового изображения.
SetMaskFromImage
Устанавливает маску, определяющую изображе- ние или цвет, которые будут использоваться для прозрачных областей.
Scale, Rescale
Изменяют размеры изображения, результат воз- вращается в виде нового изображения или со- храняется в текущем.
10.5.1
Загрузка и сохранение изображений wxImage умеет загружать или сохранять изображения в нескольких форматах,
используя специальные классы-обработчики, которые обеспечивают такую расширя- емость. Обработчики форматов wxImage также используются для других классов растровых изображений, если те не имеют соответствующей реализации данной опе- раций.
В таблице
10.3
указаны все типы обработчиков изображений, поддерживаемые на всех платформах. По умолчанию всегда загружен только обработчик wxBMPHandler.
Для того, чтобы использовать другие форматы, необходимо загрузить необходимый обработчик с помощью wxImage::AddHandler или wxInitAllImageHandlers.
Если вы хотите использовать только определенное множество форматов, то необ- ходимо поместить следующий код в ваш метод wxApp::OnInit:
18

10.5. Работа с wxImage
19
#include "wx/image.h"
wxImage::AddHandler( new wxPNGHandler );
wxImage::AddHandler( new wxJPEGHandler );
wxImage::AddHandler( new wxGIFHandler );
wxImage::AddHandler( new wxXPMHandler );
Или же можно просто вызвать wxInitAllImageHandlers();
Ниже показано несколько примеров загрузки и сохранения изображений из фай- лов и потоков. Учтите, что при загрузке файлов необходимо указывать абсолютный,
а не относительный, путь к файлу.
// Загружаем изображение, используя конструктор с указание типа файла wxImage image(wxT("image.png"), wxBITMAP_TYPE_PNG);
if (image.Ok())
{
}
// В данном случае wxImage сам определит тип файла wxImage image(wxT("image.png"));
// Загрузка в два шага wxImage image;
if (image.LoadFile(wxT("image.png")))
{
}
// Загрузка в два шага с использованием индекса изображения
// (используется для форматов, поддерживающих несколько изображениями в
// одном файле): в данном случае загружаем изображение номер два,
// если оно существует wxImage image;
int imageCount = wxImage::GetImageCount(wxT("image.tif"));
if (imageCount > 2)
image.LoadFile(wxT("image.tif"), wxBITMAP_TYPE_TIFF, 2);
// Загрузка из потока wxFileInputStream stream(wxT("image.tif"));
wxImage image;
image.LoadFile(stream, wxBITMAP_TYPE_TIF);
// Сохранение в файл image.SaveFile(wxT("image.png")), wxBITMAP_TYPE_PNG);
19

20
Глава 10. Работа с изображениями
// Сохранение в поток wxFileOutputStream stream(wxT("image.tif"));
image.SaveFile(stream, wxBITMAP_TYPE_TIF);
Все изображения сохраняются в файл в 24-битном формате, за исключением фор- матов XPM и PCX, чьи обработчики подсчитывают количество цветов и сохраняют с нужной глубиной. В JPEG формате есть дополнительная опция установки качества,
которую можно установить перед сохранением. Значение является целым числом между 0 и 100, где 0 — это наихудшее качество с высоким уровнем сжатия, а 100 —
наивысшее качество с плохим сжатием.
// Сохраняем с оптимальным качеством и компрессией image.SetOption(wxIMAGE_OPTION_QUALITY, 80);
image.SaveFile(wxT("picture.jpg"), wxBITMAP_TYPE_JPEG);
Возможно вы захотите использовать wxImage::SetOption при сохранении XPM
в поток, так как при таком сохранении не указывается имя файла, а обработчик не сможет узнать какое значение присвоить переменной языка C, которая является частью данных XPM. Например:
// Сохраняем XPM в поток image.SetOption(wxIMAGE_OPTION_FILENAME, wxT("myimage"));
image.SaveFile(stream, wxBITMAP_TYPE_XPM);
Учтите, что обработчик добавит суффикс _xpm к имени файла, которое вы ука- жете.
10.5.2
Прозрачность
Есть два способа использования прозрачности в wxImage: маска и альфа-канал.
Один цвет изображения может быть указан как цвет маски, что приведет к авто- матическому созданию объекта wxMask при конвертировании изображения в объект wxBitmap.
Также wxImage поддерживает альфа-канал. Для каждого пикселя в дополнение к байту для красного, зеленого и синего компонентов цвета, класс содержит байт,
который указывает значение непрозрачности (opacity) для данного пикселя. Значе- ние 0 соответствует прозрачному пикселю (нулевая непрозрачность), а значение 255
указывает на то, что пиксель 100% непрозрачный.
Не у всех изображений есть альфа-канал, поэтому перед использованием метода
GetAlpha необходимо проверить его наличие с помощью HasAlpha. В данный момент,
альфа-канал поддерживают только изображения, загруженные из PNG-файлов или изображения с назначенным с помощью SetAlpha альфа-каналом. Сохранение изоб- ражений с альфа-каналом пока не поддерживается. Чтобы нарисовать изображения с альфа-каналом необходимо сконвертировать изображение в wxBitmap, а далее ис- пользовать wxDC::DrawBitmap или wxDC::Blit.
В следующем коде показывается, как создается wxImage с маской. Изображение будет синим, содержащим прозрачный прямоугольник.
20

10.5. Работа с wxImage
21
// Создаем изображение с маской
// Сначала рисуем в wxBitmap wxBitmap bitmap(400, 400);
wxMemoryDC dc;
dc.SelectObject(bitmap);
dc.SetBackground(*wxBLUE_BRUSH);
dc.Clear();
dc.SetPen(*wxRED_PEN);
dc.SetBrush(*wxRED_BRUSH);
dc.DrawRectangle(50, 50, 200, 200);
dc.SelectObject(wxNullBitmap);
// Конвертируем растровое изображение (bitmap) в картинку (image)
wxImage image = bitmap.ConvertToImage();
// Устанавливаем красный как цвет маски image.SetMaskColour(255, 0, 0);
Также возможно создать маску из другого изображения. В следующем приме- ре, файл image.bmp содержит основное изображение, а mask.bmp содержит черные пиксели, которые будут указывать на прозрачные области.
// Загрузим изображение и его маску wxImage image(wxT("image.bmp"), wxBITMAP_TYPE_BMP);
wxImage maskImage(wxT("mask.bmp"), wxBITMAP_TYPE_BMP);
// Укажем черный, как цвет маски image.SetMaskFromImage(maskImage, 0, 0, 0);
Если вы загрузили изображение с диска, то можете проверить его на прозрач- ность, и получить цвет маски:
// Загружаем изображение с прозрачностью wxImage image(wxT("image.png"), wxBITMAP_TYPE_PNG);
// Получаем маску if (image.HasMask())
{
wxColour maskColour(image.GetMaskRed(),
image.GetMaskGreen(),
image.GetMaskBlue());
}
10.5.3
Преобразования
Класс wxImage поддерживает масштабирование, вращение и зеркальное отраже- ние картинки. Вот несколько примеров:
21

22
Глава 10. Работа с изображениями
// Масштабировать изображение как 200x200
// и назначить результат другому объекту.
// image1 не модифицируется.
wxImage image2 = image1.Scale(200, 200);
// Изменяем размер на 200x200
image1.Rescale(200, 200);
// Вращаем на указаное число радиан.
// image1 не модифицируется.
wxImage image2 = image1.Rotate(0.5);
// Вращаем на 90 градусов по часовой стрелке.
// image1 не модифицируется.
wxImage image2 = image1.Rotate90(true);
// Отражаем изображение по горизонтали.
// image1 не модифицируется.
wxImage image2 = image1.Mirror(true);
10.5.4
Уменьшение цветности
Если вам необходимо уменьшить количество цветов в изображении, то необходимо использовать статические методы класса wxQuantize. Нужный нам метод Quantize в качестве аргументов принимает исходное изображение, возвращаемое изображение,
опционально палитру wxPalette** для установки необходимых вам цветов в изобра- жении, а также желаемое количество цветов. Дополнительно можно указать перемен- ную типа unsigned char** для получения 8-битного представления возвращаемого изображения, а также стиль для лучшего управления возвращаемыми данными; за более детальной информации обратитесь к справочному руководству.
Данный пример показывает, как уменьшить цветность изображения до 256 цве- тов:
#include "wx/image.h"
#include "wx/quantize.h"
wxImage image(wxT("image.png"));
int maxColorCount = 256;
int colors = image.CountColours();
wxPalette* palette = NULL;
if (colors > maxColorCount )
{
wxImage reducedImage;
if (wxQuantize::Quantize(image, reducedImage,
& palette, maxColorCount))
{
22

10.5. Работа с wxImage
23
colors = reducedImage.CountColours();
image = reducedImage;
}
}
С изображением может идти палитра wxPalette (связанная с ним), например,
когда изображение было загружено из GIF-файла. Тем не менее, изображение хра- нится в RGB формате, а палитра просто указывает значение индексов в формате
RGB. Для wxImage также можно назначить палитру wxPalette, в результате чего метод SaveFile может сохранить данное изображение с ограниченным количеством цветов. Например, если в систем Windows обработчик формата BMP обнаружива- ет, что в опциях изображения указан формат wxBMP_8BPP_PALETTE, то он сохраняет изображение с палитрой; если указан формат wxBMP_8BPP, то обработчик создает па- литру из данных изображения. Некоторые обработчики сами производят уменьшение цветности (например, PCX), пока не подберут достаточное количество уникальных цветов.
Дополнительную информацию по wxPalette смотрите в разделе «wxPalette» Гла- вы 5.
10.5.5
Работа с внутренними данными wxImage
Возможно получить прямой доступ к данным изображения, используя метод
GetData, что позволяет гораздо быстрее манипулировать с данными, чем при ис- пользовании методов GetRed, GetBlue, GetGreen и SetRGB. Ниже показан пример преобразования цветного изображения в черно-белое:
void wxImage::ConvertToGrayScale(wxImage& image)
{
double red2Gray
= 0.297;
double green2Gray = 0.589;
double blue2Gray
= 0.114;
int w = image.GetWidth(), h = image.GetHeight();
unsigned char *data = image.GetData();
int x,y;
for (y = 0; y < h; y++)
for (x = 0; x < w; x++)
{
long pos = (y * w + x) * 3;
char g = (char) (data[pos]*red2Gray +
data[pos+1]*green2Gray +
data[pos+2]*blue2Gray);
data[pos] = data[pos+1] = data[pos+2] = g;
}
}
23

24
Глава 10. Работа с изображениями
10.6
Списки изображений и пакеты иконок
Иногда удобно объединить несколько изображений в один объект. Вы можете непосредственно использовать списки изображений wxImageList в своем приложении или создавать их для элементов управления wxWidgets, которые используют данные списки. Классы wxNotebook, wxTreeCtrl и wxListCtrl используют wxImageList для иконок в своих элементах. Также есть возможность просто нарисовать отдельное изображение из wxImageList в контекст устройства.
wxImageList создается с указанием высоты и ширины каждого изображения, бу- левым значением (которое указывает на то будет ли использоваться маска), а также начальным размером списка (для внутренней оптимизации). Далее необходимо доба- вить несколько изображений в формате wxBitmap или wxIcon. Для списков нельзя использовать объекты wxImage, но можно передать их через конструктор wxBitmap.
wxImageList::Add возвращает целочисленный индекс, который далее можно исполь- зовать как идентификатор изображения; после добавления в список изображение можно уничтожить, так как wxImageList делает его копию.
Далее несколько примеров создания wxImageList и добавления в него изображе- ний:
// Создание wxImageList wxImageList *imageList = new wxImageList(16, 16, true, 1);
// Добавление растрового изображения с прозрачностью из PNG
wxBitmap bitmap1(wxT("image.png"), wxBITMAP_TYPE_PNG);
imageList->Add(bitmap1);
// Добавление изображения с прозрачностью из другого растрового изображения wxBitmap bitmap2(wxT("image.bmp"), wxBITMAP_TYPE_BMP);
wxBitmap maskBitmap(wxT("mask.bmp"), wxBITMAP_TYPE_BMP);
imageList->Add(bitmap2, maskBitmap);
// Добавление растрового изображения с маской, указанной с помощью цвета wxBitmap bitmap3(wxT("image.bmp"), wxBITMAP_TYPE_BMP);
imageList->Add(bitmap3, *wxRED);
// Добавление иконки
#include "folder.xpm"
wxIcon icon(folder_xpm);
imageList->Add(icon);
Можно нарисовать изображение непосредственно в
контекст устрой- ства,
передав флаг,
который указывает как необходимо нарисовать изоб- ражение.
wxIMAGELIST_DRAW_TRANSPARENT,
например,
указывает,
что изоб- ражение рисуется с
использованием прозрачности.
Есть еще три форма- та рисования:
wxIMAGELIST_DRAW_NORMAL,
wxIMAGELIST_DRAW_SELECTED
и wxIMAGELIST_DRAW_FOCUSED.
// Рисуем все изображения из списка
24

10.6. Списки изображений и пакеты иконок
25
wxClientDC dc(window);
size_t i;
for (i = 0; i < imageList->GetImageCount(); i++)
{
imageList->Draw(i, dc, i*16, 0, wxIMAGELIST_DRAW_NORMAL|
wxIMAGELIST_DRAW_TRANSPARENT);
}
Для того, что бы назначить иконки вкладкам блокнота (notebook), необ- ходимо создать список изображений с
иконками
16x16
и вызвать метод wxNotebook::SetImageList или wxNotebook::AssignImageList. Если Вы будете ис- пользовать первый вариант, то блокнот не будет удалять список, когда будет уни- чтожатся; во втором случае блокнот принимает на себя владение списком и вам не нужно самостоятельно удалять списка изображений. После указанной выше процеду- ры при добавлении страницы в блокнот вы можете указать индекс иконки, которая будет показываться возле текста на вкладке (или вместо него, если на вкладке нет надписи). Ниже показан пример кода, где добавляется две страницы с иконками на вкладках.
// Создаем wxImageList wxImageList *imageList = new wxImageList(16, 16, true, 1);
// Добавляем несколько иконок wxBitmap bitmap1(wxT("folder.png"), wxBITMAP_TYPE_PNG);
wxBitmap bitmap2(wxT("file.png"), wxBITMAP_TYPE_PNG);
int folderIndex = imageList->Add(bitmap1);
int fileIndex = imageList->Add(bitmap2);
// Создаем блокнот с двумя страницами wxNotebook* notebook = new wxNotebook(parent, wxID_ANY);
wxPanel* page1 = new wxPanel(notebook, wxID_ANY);
wxPanel* page2 = new wxPanel(notebook, wxID_ANY);
// Назначаем список изображений notebook->AssignImageList(imageList);
// Добавляем страницы с иконками notebook->AddPage(page1, wxT("Folder options"), true, folderIndex);
notebook->AddPage(page2, wxT("File options"), false, fileIndex);
В элементах управления wxTreeCtrl и wxListCtrl используется тот аналогич- ный способ с указанием или назначением (когда элемент управления берет на себя владение) списка изображений.
Если у вас много иконок и вам трудно управлять ими с помощью индексов, вы можете написать собственный класс, который ассоциирует индексы с символьными именами. Ниже показан простейший пример такой реализации:
#include "wx/hashmap.h"
25

26
Глава 10. Работа с изображениями
WX_DECLARE_STRING_HASH_MAP(int, IconNameToIndexHashMap);
// Класс для обращения к индексам через имя class IconNameToIndex
{
public:
IconNameToIndex() {}
// Добавление изображения с именем в список изображений void Add(wxImageList* list, const wxBitmap& bitmap,
const wxString& name) {
m_hashMap[name] = list->Add(bitmap);
}
// Добавление иконки с именем в список изображений void Add(wxImageList* list, const wxIcon& icon,
const wxString& name) {
m_hashMap[name] = list->Add(icon);
}
// Поиск индекса по имени int Find(const wxString& name) { return m_hashMap[name]; }
private:
IconNameToIndexHashMap m_hashMap;
};
Класс wxIconBundle также предназначен для хранения набора изображений, но он хранит одно изображение в различных разрешениях, а не множества картинок.
Данный класс помогает подобрать системе картинку необходимого размера. Напри- мер, иконка из заголовка окна может быть меньше, чем та же иконка для файла в
Проводнике или иконка в менеджере задач. Далее показан пример использования пакета иконок (icon bundle).
// Создаем пакет с одной иконкой
#include "file16x16.xpm"
wxIconBundle iconBundle(wxIcon(file16x16_xpm));
// Добавляем иконку из файла iconBundle.Add(wxIcon(wxT("file32x32.png"), wxBITMAP_TYPE_PNG));
// Создаем пакет иконок из нескольких иконок в одном фале wxIconBundle iconBundle2(wxT("multi-icons.tif"), wxBITMAP_TYPE_TIF);
// Получает иконку с заданным размером или, если не найдена, берет иконку
// с размерами wxSYS_ICON_X, wxSYS_ICON_Y
26

10.7. Настройка графики библиотеки wxWidgets
27
Рис. 10.1: Браузер графики wxIcon icon = iconBundle.GetIcon(wxSize(16,16));
// Назначает пакет иконок приложению wxFrame* frame = new wxFrame(parent, wxID_ANY);
frame->SetIcons(iconBundle);
В системе Windows метод SetIcons извлечет из пакета иконки размером 16x16 и
32x32.
10.7
Настройка графики библиотеки wxWidgets wxArtProvider — это класс, который позволяет настраивать встроенную в wxWidgets графику приложений (art). Например, вы возможно захотите заменить стандартные иконки в HTML-справке или в стандартных диалогах, таких как про- смотрщик логов.
Для получения иконок для внутреннего использования wxWidgets использует стандартный объект wxArtProvider. Когда вашей программе нужна графическая ин- формация, вызывается метод wxArtProvider::GetBitmap (wxArtProvider::GetIcon для иконок).
У всех графических объектов есть два идентификатора: графический идентифи- катор (wxArtID) и пользовательский идентификатор (wxArtClient). Пользователь- ский идентификатор применяется, когда различным окнам необходимо использовать различные изображения для одних графических идентификаторов. Например, окно справки wxHTML использует следующий код, для изображения кнопки «Назад» на панели инструментов:
wxBitmap bmp = wxArtProvider::GetBitmap(wxART_GO_BACK,wxART_TOOLBAR);
Вы можете посмотреть идентификаторы и графику, встроенную в wxWidgets,
скомпилировав и запустив проект samples/artprov из библиотеки wxWidgets. На изоб- ражении
10.1
показано окно браузера графики.
Что бы заменить графические элементы wxWidgets создайте производный от wxArtProvider класс,
перегрузите его метод
CreateBitmap и
вызовите
27

28
Глава 10. Работа с изображениями wxArtProvider::PushProvider в вашей функции OnInit для того, чтобы wxWidgets начала использовала ваш класс. Ниже показан пример замены большинства графики из окна справки wxHTML.
// XPM’ы с графикой
#include "bitmaps/helpbook.xpm"
#include "bitmaps/helppage.xpm"
#include "bitmaps/helpback.xpm"
#include "bitmaps/helpdown.xpm"
#include "bitmaps/helpforward.xpm"
#include "bitmaps/helpoptions.xpm"
#include "bitmaps/helpsidepanel.xpm"
#include "bitmaps/helpup.xpm"
#include "bitmaps/helpuplevel.xpm"
#include "bitmaps/helpicon.xpm"
#include "wx/artprov.h"
// Класс графики class MyArtProvider : public wxArtProvider
{
protected:
virtual wxBitmap CreateBitmap(const wxArtID& id,
const wxArtClient& client,
const wxSize& size);
};
// Метод CreateBitmap wxBitmap MyArtProvider::CreateBitmap(const wxArtID& id,
const wxArtClient& client,
const wxSize& size)
{
if (id == wxART_HELP_SIDE_PANEL)
return wxBitmap(helpsidepanel_xpm);
if (id == wxART_HELP_SETTINGS)
return wxBitmap(helpoptions_xpm);
if (id == wxART_HELP_BOOK)
return wxBitmap(helpbook_xpm);
if (id == wxART_HELP_FOLDER)
return wxBitmap(helpbook_xpm);
if (id == wxART_HELP_PAGE)
return wxBitmap(helppage_xpm);
if (id == wxART_GO_BACK)
return wxBitmap(helpback_xpm);
if (id == wxART_GO_FORWARD)
return wxBitmap(helpforward_xpm);
if (id == wxART_GO_UP)
28

10.8. Итоги
29
return wxBitmap(helpup_xpm);
if (id == wxART_GO_DOWN)
return wxBitmap(helpdown_xpm);
if (id == wxART_GO_TO_PARENT)
return wxBitmap(helpuplevel_xpm);
if (id == wxART_FRAME_ICON)
return wxBitmap(helpicon_xpm);
if (id == wxART_HELP)
return wxBitmap(helpicon_xpm);
// Любые иконки wxWidgets, которые здесь не реализованы,
// будут поставлены <<родным>> классом графики.
return wxNullBitmap;
}
// Инициализация bool MyApp::OnInit()
{
wxArtProvider::PushProvider(new MyArtProvider);
return true;
}
10.8
Итоги
В этой главе мы рассмотрели использование четырех основных классов изобра- жений — wxBitmap, wxIcon, wxCursor и wxImage, а также двух классов для создания коллекций изображений — wxImageList и wxIconBundle. Также вы узнали, как мож- но заменить стандартные иконки и изображения wxWidgets своими собственными.
Примеры использования классов изображений смотрите в каталогах samples/image,
samples/listctrl и samples/dragimag дистрибутива wxWidgets.
В следующей главе мы рассмотрим классы, которые позволяют реализовать об- мен данными с помощью буфера обмена и перетаскивания (drag and drop).
29

Document Outline

  • Работа с изображениями
    • Классы изображений в wxWidgets
    • Работа с wxBitmap
      • Создание wxBitmap
      • Использование wxMask
      • Формат XPM
      • Рисование растровых изображений
      • Упаковка графических ресурсов
    • Работа с wxIcon
      • Создание wxIcon
      • Использование wxIcon
      • Назначение иконки приложению
    • Работа с wxCursor
      • Создание wxCursor
      • Использование wxCursor
      • Использование wxSetCursorEvent
    • Работа с wxImage
      • Загрузка и сохранение изображений
      • Прозрачность
      • Преобразования
      • Уменьшение цветности
      • Работа с внутренними данными wxImage
    • Списки изображений и пакеты иконок
    • Настройка графики библиотеки wxWidgets
    • Итоги


Поделитесь с Вашими друзьями:


База данных защищена авторским правом ©nethash.ru 2017
обратиться к администрации

войти | регистрация
    Главная страница


загрузить материал