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

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

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

Еще позже в документации появились указания о том, что возможно одновременное задание масок цветов и палитры — после заголовка сначала размещаются маски цветов и только затем палитра, размер которой определяется полем biClrUsed заголовка битмапа. Помимо этого, также можно найти замечание о том, что маски могут быть заданы для всех режимов, в которых число бит/пиксель равно или превышает 16, включая TrueColor (24 бита/пиксель). На практике эти расширения большинством приложений не поддерживаются.

Для проверки использовался стандартный MS Paint, который сам по возможности не выполняет анализа изображений и всю работу старается передать GDI. Это позволяет использовать его в качестве теста на возможности GDI. Для разных платформ Windows были получены следующие результаты:

Windows 3.11

Поддерживает режимы 1, 4, 8, 16, 24, 32 бит/пиксель для BI_RGB;

Режим BI_BITFIELDS не поддерживается9.

Windows–95

Поддерживает режимы 1, 4, 8, 16, 24, 32 бит/пиксель для BI_RGB;

Windows–98

Windows NT 4.0

сверх того, что может Windows–95:

Поддерживает режимы 16 и 32 бит/пиксель для BI_BITFIELDS;

Для режима 24 бита/пиксель задание масок (и BI_BITFIELDS) не поддерживается.

Для режимов 16, 24, 32 возможно задание палитры как в BI_RGB так и в BI_BITFIELDS;

Однако, при работе в 256ти цветном режиме осталось впечатление, что необязательная для 16ти, 24х и 32х бит/пиксель битмапов палитра просто игнорируется, даже если присутствует. Однако это особенность MS Paint, а не GDI. К сожалению, остальные проверенные приложения (например, Photo Shop 5.0) вообще отказались работать с HiColor форматами (16 и 32 бит/пиксель).

Это значит, что для экспорта изображений приложение должно использовать по возможности старые, проверенные и широко распространенные форматы 1, 4, 8 бит/пиксель с полной палитрой (в случае OS/2 приходилось наблюдать ошибки при чтении битмапов с сокращенной палитрой); либо TrueColor в стандартном варианте — без палитры и без масок цветов. А вот при чтении битмапа целесообразно допускать все эти возможные варианты, что обеспечит совместимость с битмапами, создаваемыми другими приложениями, даже в ближайшем будущем.

Таким образом для битмапов Win32 надо обращать внимание на:

возможно отрицательную высоту битмапа;

режим сжатия BI_BITFILEDS — если он задан, то после заголовка есть 3 двойных слова с масками цветовых компонент; если же задан режим BI_RGB, BI_RLE4 или BI_RLE8, то масок нет (предполагаются стандартные маски 5–5–5 или 8–8–8);

для форматов 1, 4 и 8 бит на пиксель палитра обязательна, а для 16, 24 и 32 бит на пиксель палитра может отсутствовать (то есть нулевое значение biClrUsed интерпретируется либо как максимальный размер палитры, либо как ее отсутствие — смотря по числу бит на пиксель). Для HiColor или TrueColor режимов палитра является лишь рекомендуемой, облегчающей процесс отображения полноцветного битмапа на устройстве, поддерживающем палитры. Именно поэтому в примере на странице 57 при определении размера палитры значение поля biBitCount сравнивалось с 8, а не проверялось строгое равенство 24 битам на пиксель — максимальный размер палитры определен только для 2х, 16ти и 256ти цветных битмапов, а для форматов с 16тью, 24мя и 32мя битами на пиксель для задания палитры необходимо задать поле biClrUsed. По умолчанию в HiColor и TrueColor битмапах палитра отсутствует. Если задан и режим BI_BITFIELDS, и biClrUsed не равен 0, то палитра размещается непосредственно после масок.

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

Для сохранения битмапа необходимо разобраться со всеми необходимыми структурами данных, заполнить их, а затем записать в файл. Задачу можно существенно упростить, если считать, что битмап загружен в виде «Packed DIB», что существенно позволяет сохранение битмапа свести, аналогично чтению, к нескольким функциям.

В ранее приводимых примерах я использовал собственную структуру _DIB, описывающую загруженный в память DIB. Она определена в примере на странице 52, вместе с включением необходимых заголовочных файлов и определением вспомогательных символов. Помимо этого она будет применяться в данном примере, а также с ее помощью будут выполнены операции по преобразованию DIB в DDB (стр. 63) и наоборот — DDB в DIB (стр. 64).

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

BOOL StoreDIBtoFile (LPSTR lpszFileName, LP_DIB lpDib) {

BITMAPFILEHEADER bmfh; // заголовок файла битмапа

HFILE hf;

BOOL a = FALSE;

DWORD dwSize;

hf = _lcreat (lpszFileName, 0);

if (hf != HFILE_ERROR) {

// заполняем и записываем заголовок файла

bmfh.bfType = DIB_SIGNATURE;

bmfh.bfSize = 0L;

bmfh.bfReserved1 = bmfh.bfReserved2 = 0;

bmfh.bfOffBits =

sizeof (BITMAPFILEHEADER) +

(LPSTR) (lpDib->lpImage) - (LPSTR) (lpDib->lpDibHdr);

// в нашем случае это всегда «Packed DIB», поэтому разница двух указателей

// возвратит расстояние между ними.

if (lpDib->lpDibHdr.biSize == sizeof (BITMAPCOREHEADER)) {

// определяем размер изображения

#define lpbmch ((LPBITMAPCOREHEADER) (lpDib->lpDibHdr))

dwSize = ( (lpbmch->bcWidth * lpbmch->bcBitCount + 31) >> 3) & ~3L;

dwSize *= lpbmch->bcHeight;

#undef lpbmch

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

dwSize += bmfh.bfOffBits;

} else {

// размер изображения можно получить из BITMAPINFOHEADER

dwSize = bmfh.bfOffBits + lpDib->lpDibHdr.biSizeImage;}

_hwrite (hf, (LPVOID)&bmfh, sizeof (bmfh));

// записываем собственно DIB

_hwrite (hf, (LPVOID) (lpDib->lpDibHdr), dwSize - sizeof (BITMAPFILEHEADER));

_lclose (hf);

a = TRUE;}

return a;}

Большая часть трудностей, связанных с анализом информации о битмапе, переносится на функции, осуществляющие загрузку битмапа (LoadDIBfromFile, стр. 52, LoadDIBfromResources, стр. 52) и преобразование из DDB в DIB (ConvertDDBtoDIB, стр. 64)

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

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

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

Сначала мы рассмотрим функцию, осуществляющую перенос изображения из битмапа на устройство, не изменяющее размеров изображения.

int SetDIBitsToDevice (

hDC, nDestX, nDestY, nDestWidth, nDestHeight,

nSrcX, nSrcY, nStartScan, nCountScan, lpImage, lpDibInfo, nColorUse);

Параметры hDC, nDestX, nDestY, nDestWidth и nDestHeight указывают устройство, на котором осуществляется отображение битмапа, положение и размер выводимого изображения. Существенно отметить, что в данном случае используется система координат устройства.

Параметры nSrcX и nSrcY задают положение исходного прямоугольного изображения в битмапе. Если вы задаете эти координаты не 0, то помните, что у независимых от устройства битмапов начало отсчета системы координат помещается в левый–нижний угол, что несколько необычно.

Параметр lpDibInfo является указателем на структуру BITMAPINFO (BITMAPCOREINFO), определяющую характеристики битмапа, а параметр lpImage указывает на область памяти, содержащую данные изображения.

Еще два параметра nStartScan и nCountScan указывают на фрагмент битмапа, определенный в области lpImage. nStartScan указывает номер строки развертки, с которой начинается изображение, а nCountScan указывает число строк, отображаемых этой операцией. С помощью этих параметров можно разбить процесс вывода одного большого битмапа на несколько вызовов функции SetDIBitsToDevice, каждый из которых перенесет только небольшую часть строк изображения. Это может существенно сократить требуемое для отображения битмапа количество памяти (полная картинка 1280 x 1024, 24 бита/пиксель занимает более 3M).

Последний параметр nColorUse определяет применение цветов битмапом. Он может быть DIB_RGB_COLORS, если таблица определения цветов содержит записи RGBQUAD; или он может быть DIB_PAL_COLORS, если таблица определения цветов содержит массив 16ти разрядных номеров цветов в текущей палитре.

В Windows требуется, что бы таблица определения цветов содержала записи RGBQUAD10, если битмап сохранен в виде файла, в виде ресурсов приложения, или если он каким–либо способом передается другому приложению. Таким образом DIB_PAL_COLORS может применяться, только если вы сами создаете и используете DIB, не сохраняя его и никому не передавая, и при этом текущая системная палитра полностью удовлетворяет вашим требованиям, что весьма и весьма редкий случай. Более того, при использовании DIB_PAL_COLORS вы обязаны проследить, что бы количество цветов, определяемых индексами было четным. Это связано с тем, что строки растра в DIB выравниваются на границу двойного слова и, одновременно, должны начинаться на такой границе. Размер заголовка (BITMAPINFOHEADER) кратен 4, одна запись RGBQUAD тоже имеет длину 4 байта; таким образом при использовании DIB_RGB_COLORS строка растра всегда начнется на границе двойного слова. А вот в случае DIB_PAL_COLORS одна запись в таблице определения цветов — 16ти разрядное число, тогда вам необходимо проследить, что бы таблица содержала четное число записей и ее длина была бы кратна 4 байтам.

Функция возвращает число строк развертки, перенесенных данной операцией.

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

int StretchDIBits (

hDC, nDestX, nDestY, nDestWidth, nDestHeight,

nSrcX, nSrcY, nSrcWidth, nSrcHeight, lpImage, lpDibInfo,

nColorUse, dwROP);

Параметры hDC, nDestX, nDestY, nDestWidth, nDestHeight задают устройство, на котором осуществляется отображение, положение и размеры изображения, как оно должно быть отображено.

Параметры nSrcX, nSrcY, nSrcWidth, nSrcHeight задают положение и размеры исходного изображения в битмапе. Начало отсчета системы координат битмапа находится в левом–нижнем углу битмапа, единицы соответствуют пикселям битмапа.

Параметр lpDibInfo указывает на структуру BITMAPINFO (BITMAPCOREINFO), а lpImage на буфер, содержащий данные изображения.

Параметр nColorUse указывает на способ задания таблицы определения цветов, обычно DIB_RGB_COLORS, а параметр dwROP задает индекс растровой операции, выполняемой при переносе изображения.

Так как при переносе может изменяться размер изображения, то функция использует текущий режим сжатия изображения, заданный функцией SetStretchBltMode.

Функция возвращает число строк развертки, перенесенных данной операцией.

Использование промежуточного DDB при работе с DIB

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

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

Основа способа проста:

сначала надо загрузить DIB (обычно в виде «Packed DIB »)

преобразовать DIB в DDB с помощью функции CreateDIBitmap

выполнить требуемые операции над DDB (см. «Работа с зависимым от устройства битмапом», стр. 45)

осуществить обратное преобразование DDB в DIB с помощью функции GetDIBits

Первая операция — загрузка DIB — уже подробно рассмотрена в разделе «Загрузка независимых от устройства битмапов.», на ней останавливаться сейчас не будем. Вторая операция позволяет получить хендл DDB (HBITMAP), который можно использовать для выполнения требуемых операций над битмапом. Так, например, такой битмап может быть выбран в совместимый контекст устройства или использован для создания кисти и т.д.

Следует отметить, что определяя свойства преобразования DIB в DDB надо правильно определить цель такого преобразования. Если вы планируете выполнить редактирование DIB, то важно не испортить хранимое изображение; часто может быть целесообразно назначить цветовое разрешение DDB достаточно высоким, скажем TrueColor, даже если он реально будет отображаться на устройстве, имеющем существенно меньшее цветовое разрешение. Либо воспользоваться DIB–секциями, которые также возвращают HBITMAP. Однако еще чаще встречается другой вариант — преобразование DIB в DDB выполняется для ускорения процесса вывода. Так, например, если битмап применяется для закраски фона окна (в качестве «обоев»), то особую важность приобретает скорость вывода, в то время как качество цветопередачи должно только лишь соответствовать возможностям аппаратуры и применяемому режиму.

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

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

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

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