Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СПро - все лк.pdf
Скачиваний:
65
Добавлен:
16.03.2016
Размер:
1.35 Mб
Скачать

Шаг 1: создаются прототипы функций, имеющие те же параметры, что и необходимые функции внутри *.dll. Для нашего примера это будет выглядеть так: typedef BOOL (WINAPI * Inc)(int i);

Шаг 2: объявляется переменная типа указателя на данную функцию:

Inc pI;

Шаг 3: в программе осуществляется загрузка библиотеки:

HINSTANCE hL; hL=LoadLibrary("funlib.dll");

Шаг 4: объявленному указателю на функцию присваивается адрес функции из *.dll:

pI=(Inc)GetProcAddress(hL,(LPCSTR)2);

Шаг 5: функция используется по назначению: cout<<pI(6);

Шаг 5: после использования выгружается из памяти:

FreeLibrary(hL);

Целиком рассмотренный пример выглядит следующим образом:

#include "stdafx.h" #include "iostream.h" #include "windows.h"

HINSTANCE hL;

typedef int (CALLBACK * Inc)(int i); Inc pI;

int main(int argc, char* argv[]) { hL=LoadLibrary("1111.dll");

pI=(Inc)GetProcAddress(hL,(LPCSTR)2);

cout<<pI(6);

FreeLibrary(hL); return 0;

}

Наличие *.dll требуется только во время запуска *.exe файла.

Лекция №13: Представление графической информации

Битовые образы

Битовые или растровые образы (bitmap) представляют собой метод хранения графической информации в программах для Windows. Битовый образ – это цифровое представление изображения. Каждому пикселю (точке) изображения соответствует один или более бит битового образа, которые

102

определяют цвет пикселя. Таким образом, если, например, нам необходимо запомнить монохромное (черно-белое) изображение, мы можем использовать только один бит (0-черный, 1-белый) для запоминания одной точки рисунка. Битовые образы имеют как достоинства, так и недостатки. К достоинствам можно отнести хорошую передачу изображения (именно они чаще всего используются для хранения фотографий, сложных рисунков), ограниченную только воспроизводящим оборудованием (видео картой и монитором) цветовую гамму. Существенными недостатками является большой объем памяти для хранения и сложные алгоритмы преобразования битовых образов при выводе на конкретное устройство отображения (масштабирование, соответствие реальной и доступной цветовых гамм и т.п.).

Битовые образы, не зависящие от устройства.

Формат DIB (device independent bitmap) содержит таблицу цветов, которая содержит информацию о преобразовании пикселей в RGB формат. Фактически, данный формат не является объектом GDI, однако является очень удобной формой для хранения и передачи изображения между программами и компьютерами. Каждому пользователю компьютера известен этот формат – это не что иное, как файл с расширением *.bmp. Приведем описание формата этого файла.

Файл *.bmp начинается с секции заголовка, определенной структурой BITMAPFILEHEADER. Эта структура имеет пять полей (таблица 13.1):

Таблица 13.1 – Поля структуры BITMAPFILEHEADER

Поле

Размер

Описание

bfType

WORD

Байты «ВМ» для битовых образов

bfSize

DWORD

Общий размер файла

bfReserved1

WORD

Установлено в 0

bfReserved2

WORD

Установлено в 0

bfOffBits

DWORD

Смещение битового образа от начала

 

 

файла

За этой информацией следует другой заголовок, определенный структурой BITMAPINFOHEADER. Структура имеет 11 полей (таблица 13.2).

Таблица 13.2 – Поля структуры BITMAPINFOHEADER

Поле

Размер

Описание

biSize

DWORD

Размер структуры в байтах

biWidth

LONG

Ширина битового образа в пикселях

biHaight

LONG

Высота битового образа в пикселях

biPlanes

WORD

Установлено в 1

biBitCount

WORD

Число битов цвета на пиксель (1,4,8,24)

biCompression

DWORD

Схема компрессии (если нет – 0)

 

 

103

biSizeImage

DWORD

Размер битов битового образа в байтах (нужен

 

 

только при компрессии)

biXPelsPerMeter

LONG

Разрешение в пикселях на метр по горизонтали

biYPelsPerMeter

LONG

Разрешение в пикселях на метр по вертикали

biClrUsed

DWORD

Число цветов, используемых в изображении

biClrImportant

DWORD

Число важных цветов в изображении

Приведенная структура может иметь различный размер, определяемый полем biSize. Первые 5 параметров являются обязательными. Остальные могут присутствовать в файле, могут и нет. Кроме этого, пользователь может добавлять свои оригинальные записи в конец структуры. Если biClrUsed установлено в ноль и число битов на пиксель равно 1,4,8, то сразу за данной структурой следует таблица цветов, состоящая из двух или более структур RGBQUAD (при 1 – две, при 4 – шестнадцать, и т.д.), каждая из которых определяет значение цвета:

Таблица 13.3 – Поля структуры RGBQUAD

Поле

 

Размер

Описание

rgbBlue

BYTE

 

Интенсивность голубого

rgbGreen

BYTE

 

Интенсивность зеленого

rgbRed

BYTE

 

Интенсивность красного

rgbReserved

BYTE

 

Равно 0

Число структур RGBQUAD может быть напрямую задано в поле biClrUsed.

За таблицей цветов следует массив битов, определяющих битовый образ. Этот массив начинается с нижней строки пикселей. Каждая строка начинается с левого пикселя. Каждый пиксель представлен 1, 4, 8 или 24 битами. Во-первых трех случаях число, записанное в битовом образе определяет номер RGBQUADструктуры в таблице цветов. В случае 24-х бит – это, фактически, и есть 3 байта RGB-представления цвета. В последнем случае таблица цветов может отсутствовать.

Для вывода битовых образов, не зависящих от устройства, существует несколько функции GDI. Первая из них позволяет копировать битовый образ в

контекст устройства:

 

int SetDIBitsToDevice(

 

HDC hdc,

// указатель на контекст устройства

int

XDest,

// x-координата верхнего левого угла

int

YDest,

// y-координата верхнего левого угла

DWORD

dwWidth, // ширина выводимого изображения

DWORD

dwHeight, // высота выводимого изображения

int

XSrc,

// x-координата отступа в изображении

 

 

104

int YSrc,

// y-координата отступа на контексте

UINT

uStartScan,

// первая сканируемая линия

изображения

 

 

UINT

cScanLines,

// число сканируемых линий

CONST

VOID *lpvBits, // адрес битового образа

CONST BITMAPINFO *lpbmi, //адрес структуры BITMAPINFO

UINTfuColorUse // признак RGB или палитры

);

Следует заметить, что в функции используется структура BITMAPINFO, а не присутствующая в файле BITMAPINFOHEADER, которая определена в

Windows как:

typedef struct tagBITMAPINFO {

BITMAPINFOHEADER bmiHeader; // Уже знакомая нам структура

RGBQUAD

bmiColors[1]; // Таблица цветов

} BITMAPINFO;

 

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

int StretchDIBits(

 

HDC

hdc, // указатель на контекст устройства

int

XDest,

// x-координата верхнего левого угла в контексте

int

YDest,

// y-координата верхнего левого угла в контексте

int nDestWidth, // ширина выводимого изображения в контексте int nDestHeight,// высота выводимого изображения в контексте int XSrc,//x-координата верхнего левого угла выводимой части изображения

int YSrc,//у-координата верхнего левого угла выводимой части изображения int nSrcWidth, // ширина выводимого изображения в битовом образе

int nSrcHeight, //высота выводимого изображения в битовом образе CONST VOID *lpBits, // адрес битового образа

CONST BITMAPINFO *lpBitsInfo, // адрес структуры BITMAPINFO

UINT iUsage, // флаг использования цвета DWORD dwRop // растровая операция

);

Флаг использования цвета определяет, есть ли в структуре BITMAPINFO таблица палитры (значение флага – DIB_PAL_COLORS) или в битовом образе содержится полная информация о цвете (DIB_RGB_COLORS). Последний параметр функции определяет код растровой операции. Наиболее часто используемые из них:

105

BLACKNESS Заполняет выбранную область приемника черным цветом

DSTINVERT Инвертирует выбранную область приемника NOTSRCCOPY Копирует изображение с инверсией. SRCCOPY Копирует изображение

WHITENESS Заполняет выбранную область приемника белым цветом

Битовые образы, зависящие от устройства

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

В первом случае каждому пикселю на экране ставится в соответствие некоторое количество бит. Например, если монитор может отобразить 256 цветов, то используется 8 байт на один пиксель. Для каждой скан-линии (строки растра) первый байт представляет цвет самого левого пикселя, второй байт – следующего пикселя и т.д. Подобная организация видеопамяти, бала, например в CGA – мониторах.

Пример второго вида организации битовых образов – это EGA и VGA – мониторы, которые в большинстве стандартов поддерживают плоскостное представление изображения. Цветной битовый образ для 16-цветного VGA использует 4 цветовые плоскости для представления 16 цветов. Массив битов начинается с верхней скан-линии. Цветовые плоскости для каждой скан-линии хранятся последовательно: красная плоскость – первой, зеленая плоскость – второй, затем голубая плоскость и плоскость интенсивности. Каждая плоскость имеет свой адрес в оперативной памяти.

На основе вышеизложенного можно сделать вывод, что в каждом конкретном случае зависимый битовый образ организован по-разному. И если, программа создает сама битовый образ (например, на основе функций

CreateBitmap, CreateBitmapInderect), то она должна сама определять тип,

количество цветовых плоскостей. Формат данных функций следующий:

HBITMAP MyBitmap1, MyBitmap2;

BITMAP MyStruct;

MyBitmap1=CreateBitmap(nWidth, nHeight, cPlanes, cBitsPerPel, lpvBits);

MyBitmap2=CreateBitmapInderect(&MyStruct);

где nWidth – ширина создаваемого битового образа, nHeight – высота создаваемого битового образа, cPlanes – количество битовых плоскостей, cBitsPerPel – число битов на один пиксель, lpvBits – указатель на битовый образ.

Структура BITMAP содержит перечисленные данные непосредственно.

106

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

HBITMAP MyBitmap;

MyBitmap = CreateCompatibleBitmap(hdc, xWidth,yHeght);

где hdc – описатель контекста устройства, остальные два параметра определяют ширину и высоту создаваемого битового образа. Созданный таким образом битовый образ будет иметь структуру, определяемую характеристиками устройства.

Теперь перейдем к вопросу вывода зависимого битового образа на конкретное устройство. Для данного вида графической информации не существует функций, осуществляющих непосредственный вывод в контекст устройства (подобных SetDIBitsToDevice и StretchDIBits для независимых битовых образов) на основе описателя битовых образов (HBITMAP). Для их вывода используется следующий механизм: Битовый образ, выбранный в одном контексте, может быть скопирован в другой контекст. Таким образом, в процессе участвуют два контекста: первый (обычный), в который необходимо скопировать битовый образ, и второй – в котором содержится изображение. Второй контекст, в данном случае, необходимо создать; создается он в памяти и не соответствует конкретному устройству вывода. Он так и называется – контекст памяти. Для того, чтобы дальнейшая работа по копированию битовых образов происходила без проблем, оба контекста должны быть совместимыми, или, говоря другими словами, контекст памяти необходимо создать на основе контекста устройства. Это делается при помощи следующей функции:

HDC hdcMem;

hdcMem = CreateCompatibleDC(hdc);

где hdc – описатель контекста, куда будет вестись вывод изображения. Второй этап заключается в выборе битового образа в контекст памяти по

тому же образу, каким любой объект GDI выбирается в контекст устройства:

SelectObject(hdcMem,MyBitmap);

И только после этого можно скопировать битовый образ в контекст устройства:

BitBlt(hdc, xDest, yDest, xWidth, yHeight, hdcMem, xSrc, ySrc, dwROP);

где xDest, yDest, xWidth, yHeight – определяют координаты прямоугольника на контексте устройства, в который осуществляется вывод

107