47952 (597372), страница 15

Файл №597372 47952 (Основы графического вывода) 15 страница47952 (597372) страница 152016-07-30СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 15)

Эта функция может использоваться со всеми растровыми операциями, не применяющими контекст–источник. Из именованных растровых операций это:

BLACKNESS

— закрасить все черным

DSTINVERT

— инвертировать изображение (сделать "негатив")

PATCOPY

— закрасить кистью

PATINVERT

— закрасить инвертированной кистью

WHITENESS

— закрасить все белым

Эта функция часто используется для начальной закраски областей (операции BLACKNESS, WHITENESS, PATCOPY) и для выделения фрагментов (DSTINVERT).

Следующая функция, которую мы рассмотрим:

BOOL BitBlt (

hDestDC, nDestX, nDestY, nDestWidth, nDestHeight,

hSrcDC, nSrcX, nSrcY, dwROP);

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

Отдельно надо рассмотреть случай, когда один из контекстов является цветным, а другой черно–белым — при этом особым образом осуществляется преобразование цветов:

при переходе от монохромного к цветному цвет, закодированный 1, соответствует цвету фона (задаваемому функцией SetBkColor), а цвет 0 — цвету текста (функция SetTextColor).

при переходе от цветного к монохромному считается, что если цвет точки совпадает с цветом фона, то эта точка кодируется цветом 1, иначе 0.

Самая мощная функция, выполняющая растровые операции:

BOOL StretchBlt (

hDestDC, nDestX, nDestY, nDestWidth, nDestHeight,

hSrcDC, nSrcX, nSrcY, nSrcWidth, nSrcHeight, dwROP);

позволяет не только передать изображение между разными контекстами, но и осуществить масштабирование изображения. При масштабировании возможно два случая:

изображение увеличивается, то некоторые строки (столбцы) будут дублироваться;

изображение уменьшается, то некоторые строки (столбцы) будут комбинироваться в одну строку (столбец).

Объединение строк (столбцов) при сжатии может осуществляться различными способами, которые выбираются с помощью функции

UINT SetStretchBltMode (hDC, nMode);

параметр nMode задает режим объединения строк:

BLACKONWHITE

выполняется операция И (AND). В результате получается, что черный цвет имеет "приоритет" над белым — сочетание черного с белым рассматривается как черный

WHITEONBLACK

выполняется операция ИЛИ (OR). При этом "приоритет" принадлежит белому над черным — сочетание черного с белым дает белый

COLORONCOLOR

при этом происходит простое исключение строк (столбцов).

HALFTONE 1

только в Win32 API; происходит усреднение цвета объединяемых точек.

Независимые от устройства битмапы

У уже рассмотренных зависимых от устройства битмапов имеется один очень серьезный недостаток — их организация отражает организацию видеопамяти того графического устройства, для которого они были спроектированы. При этом возникают большие сложности с переносом битмапов с одного устройства на другое, особенно при создании битмапов, которые будут сохраняться в виде файлов и позже переносится на другие компьютеры. Достаточно универсальным является только лишь монохромный битмап, который легко может быть отображен на любом цветном устройстве, однако такое ограничение является крайне неудобным для конечного пользователя.

Для цветных битмапов сложности возникают даже при их отображении на однотипных устройствах. Например, SVGA адаптеры часто используют логическую палитру, задающую набор воспроизводимых цветов. При отображении одного и того же цветного битмапа на устройствах, использующих разные палитры, результат будет различным.

Наличие этих сложностей привело к появлению новых видов битмапов, так называемых независимых от устройства битмапов (Device Independed Bitmap, DIB). Такой битмап отличается от обычного тем, что дополнительно содержит данные, определяющие соответствие цветов, используемых битмапом, реальным цветам. Благодаря этому независимый от устройства битмап может быть отображен практически на любом графическом устройстве, поддерживающем операции по обмену битовыми образами, с минимальными искажениями цвета.

На практике, начиная с версий Windows 3.x для хранения изображений (в виде .bmp файлов или ресурсов приложения) используются только независимые от устройства битмапы.

Формат независимого от устройства битмапа

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

Некоторые сложности связаны с наличием нескольких различных видов DIB–файлов. Первоначально (в самых ранних версиях Windows и OS/2 использовался битмап в его простейшем виде, называемом в документации форматом OS/25. В дальнейшем, по мере развития GDI появился формат Windows, который для приложений Windows долгое время являлся фактически стандартом. Этот вид битмапов дожил до платформы Win32, когда к нему было добавлено несколько новых возможностей, правда без изменения заголовка. В дальнейшем развитие Windows битмапов пошло стремительно — практически в каждой новой версии Windows добавляется что–то новое и в заголовках битмапов появляются новые поля. Так появились битмапы 4ой версии (для Windows–95 и Windows NT 4.0) и даже 5ой (для Windows NT 5.0). Скорее всего этот процесс так скоро не остановится.

Утешает в этом два соображения:

Первое: все старые форматы битмапов поддерживаются. Таким образом, если ваше приложение само создает битмап, то он будет корректно обрабатываться и в последующих версиях Windows.

Второе: при загрузке битмапа (а он может быть создан в системе, разработанной позже вашего приложения), можно так построить алгоритм, что анализировать заголовок не потребуется. В этом случае ваше приложение опять–таки может использовать новые форматы битмапов (по крайней мере до тех пор, пока вы не собираетесь самостоятельно анализировать изображение).

Рисунок 18. Структура независимого от устройства битмапа.

Собственно независимый от устройства битмап содержит несколько структур данных, описывающих его характеристики. Эти структуры следуют друг за другом непрерывно, без промежутков. Если говорить о структуре DIB в общем, не вдаваясь в подробности описания этих структур данных, то его формат сохраняется во всех существующих версиях Windows.

Заголовок битмапа содержит данные о его размере (размере всего битмапа в байтах) и расстояние от начала файла до хранимого в нем изображения. В таком виде битмап хранится либо в файле, либо в виде ресурсов приложения. Загрузка битмапа может выполняться двумя разными способами:

В простейшем случае все, кроме заголовка файла, помещается в одну область данных (в случае 16ти разрядных платформ надо учитывать, что размер может быть существенно больше 64К). Битмап, загруженный таким образом, называется упакованным (packed DIB).

В другом случае битмап располагается в двух областях — в первой находится заголовок битмапа и данные о соответствии цветов (палитра, либо заменяющие ее данные), а во второй — собственно изображение.

Первый способ удобен при считывании битмапа с диска или из ресурсов приложения, второй — при создании нового битмапа в приложении, когда размер области данных для хранения изображения может быть заранее неизвестен (его можно узнать из заголовка битмапа). Многие функции GDI, работающие с независимыми от устройства битмапами, требуют задания двух указателей: на информацию о битмапе и на данные изображения. Однако некоторые функции ориентированы на использование упакованного битмапа, и тогда требуют задания хендла глобального блока памяти, содержащего упакованный DIB. С этой точки зрения первый способ (с использованием упакованного битмапа) универсален — вы можете легко вычислить указатель на данные изображения внутри единого блока (например, исходя из данных в заголовке файла).

Загрузка независимых от устройства битмапов

Формат заголовка файла одинаков для всех версий битмапов; он описывается структурой BITMAPFILEHEADER:

typedef struct tagBITMAPFILEHEADER {

WORD bfType;

DWORD bfSize;

WORD bfReserved1;

WORD bfReserved2;

DWORD bfOffBits;

} BITMAPFILEHEADER;

Поле bfType, должно быть содержать две буквы "BM" (значение 0x4D42).

Поле bfSize указывает полный размер файла, включая этот заголовок. Обратите внимание на то, что размер задается двойным словом, так как может существенно превышать 64K. Например битмап 1280x1024, 24 бита/пиксель имеет размер более 3M. Вообще говоря, это поле может быть не заполнено; хотя и крайне редко, но может даже оказаться, что там указана некорректная величина, вместо правильного размера или 0. По крайней мере для битмапов OS/2 в поле bfSize может оказаться величина, равная размеру заголовка файла плюс заголовок битмапа (26). Во всех случаях лучше исходить не из этой величины, а из реального размера файла.

Поля bfReserved1 и bfReserved2 оба содержат 0. По крайней мере так считает Microsoft. В битмапах OS/2 часто эти поля содержат ненулевые данные.

Поле bfOffBits указывает адрес, с которого в данном файле размещаются собственно данные изображения. Этим полем удобно пользоваться для получения размера заголовка битмапа и данных о его цветах, а заодно для вычисления адреса начала данных изображения.

Так, благодаря наличию поля bfOffBits, можно сформулировать универсальный алгоритм загрузки битмапа в память, не зависящий от версии битмапа и его характеристик. В этом примере мы будем ориентироваться на работу с функциями Windows API, что позволяет сделать более компактный, переносимый код, помимо этого введем дополнительную структуру, описывающую DIB. Она будет удобна по двум причинам — во–первых, после загрузки DIB удобно возвращать два указателя, которые могут понадобиться в дальнейшем, плюс хендл блока памяти, содержащего битмап; все это проще хранить в одной структуре. Во–вторых, эту же структуру мы сможем использовать еще раз, когда рассмотрим загрузку битмапов из ресурсов приложения. Подробнее обо всех указателях и их типах — см. в разделе “Заголовок независимого от устройства битмапа”.

#define STRICT

#include

#include

// описываем структуру, содержащую информацию о битмапе

typedef struct _DIB {

HGLOBAL hglbDib; // хендл блока памяти или ресурса

LPBITMAPINFOHEADER lpDibHdr; // указатель на заголовок битмапа

LPSTR lpImage; // указатель на изображение

UINT uDibFlags; // флаг 1-загружен из файла, 2-из ресурса

} FAR* LP_DIB;

#define DIB_FILE 1

#define DIB_RESOURCE 2

#define DIB_SIGNATURE 0x4D42

#ifdef __NT__

#define _memcpy_ (to,from,sz) CopyMemory ((LPVOID) (to), (LPVOID) (from), (sz))

#else

#define _memcpy_ (to,from,sz) hmemcpy ((void huge*) (to), (void huge*) (from), (sz))

#endif

BOOL LoadDIBfromFile (LP_DIB lpDib, LPSTR lpszFileName)

{HFILE hFile;

DWORD dwSize;

BITMAPFILEHEADER bmfh;

// инициализируем возвращаемые данные:

lpDib->hglbDib = NULL;

lpDib->lpDibHdr = (LPBITMAPINFOHEADER)NULL;

lpDib->lpImage = (LPSTR)NULL;

lpDib->uDibFlags = 0;

// открываем файл с битмапом для чтения

hFile = _lopen (lpszFileName, READ);

if (hFile == HFILE_ERROR) return FALSE;

// определяем размер упакованного битмапа

dwSize = _llseek (hFile, 0L, 2); _llseek (hFile, 0L, 0);

if (dwSize >= sizeof (bmhf)) dwSize -= sizeof (bmhf);

// выделяем блок для хранения упакованного битмапа

lpDib->lpDibHdr = (LPBITMAPINFOHEADER)GlobalAllocPtr (GHND, dwSize);

if (lpDib->lpDibHdr != (LPBITMAPINFOHEADER)NULL) {

// считываем заголовок файла

if ( (_lread (hFile, &bmhf, sizeof (bmhf)) == sizeof (bmhf)) &&

(bmhf.bfType == DIB_SIGNATURE)) {

// если заголовок успешно считан, считываем сам битмап

if (_hread (hFile, lpDib->lpDibHdr, dwSize) == dwSize) {

// и устанавливаем нужные поля структуры _DIB:

lpDib->hglbDib = GlobalPtrHandle (lpDib->lpDibHdr);

lpDib->lpImage = (LPSTR) (

(char huge*) (lpDib->lpDibHdr) + bmhf.bfOffBits - sizeof (bmhf));

lpDib->uDibFlags = DIB_FILE;}}

// если где-то возникла ошибка - освобождаем память

if (lpDib->uDibFlags == 0) {

GlobalFreePtr (lpDib->lpDibHdr);

lpDib->lpDibHdr = (LPBITMAPINFOHEADER)NULL;}}

_lclose (hFile);

Характеристики

Тип файла
Документ
Размер
4,85 Mb
Тип материала
Учебное заведение
Неизвестно

Список файлов книги

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
7027
Авторов
на СтудИзбе
260
Средний доход
с одного платного файла
Обучение Подробнее