Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ИГС / Lab_02 / labor_02pm.doc
Скачиваний:
10
Добавлен:
17.04.2018
Размер:
699.9 Кб
Скачать

25

Московский институт электронной техники

Кафедра ИПОВС

Лабораторная работа 2

«Композиция двухмерных аффинных преобразований. Моделирование движения объектов в плоскости».

Приложение.

«Использование графических вставок в bmp-файлах».

Содержание

1. Введение _______________________________________________________ стр. 1

2. Графические вставки из bmp-файлов вDOSпрограммах ______________ стр.1

3. Графические вставки из bmp-файлов вWINпрограммах ______________ стр.7

4. Графические вставки из bmp-файлов вDOSпрограммах в режиме работы с видеостраницами ____________________________________________________ стр.9

5. Графические вставки из bmp-файлов вWINпрограммах в режиме работы с оперативной памятью _________________________________________________ стр.14

6. Перемещение по экрану графических вставок из bmp-файлов вDOSпрограммах __________________________________________________________________ стр.16

7. Перемещение по экрану графических вставок из bmp-файлов вWINпрограммах. Использование двух контекстов памяти ___________________________ стр.19

8. Использование набора bmp-файлов для создания эффекта движения. Чтениеbmp-файлов из ресурсов программы. ___________________________ стр.20

9. Использование набора bmp-файлов для создания эффекта движения. Загрузкаbmp-файлов в контекст памяти. ___________________________ стр.23

!!!! Замечание.

Эта лабораторная работа была создана несколько лет назад, во времена, когда еще применялась операционная система Microsoft-DOS. Поэтому здесь рассматриваются вопросы программирования графики как в операционной системеDOS, так и в системеWINDOWS.

Введение.

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

Графические вставки из bmp-файлов в dos программах.

Посмотрим, как можно подключить bmp-файл кDOSпрограмме. Возьмем, для примера, программуmov01DOS.cpp, В этой программе в качестве фона будем использовать, какую ни будь картину, хранящуюся вbmp-файле. Сначала скажем несколько слов о графической системе, которая используется вDOSпрограммах.

При работе с компилятором BORLANDC3.1 мы устанавливаем видеоадаптер в режим работыVGA, и выбираем графическую моду равную 1 ли 2. Соответствующий код имеет вид.

int mode =2, driver = 9;

initgraph(&driver, &mode,"c:\\borlandc\\bgi");

В этом режиме работы видеоадаптера используется механизм цветовой палитры. Палитра имеет 16 цветов, которые можно одновременно вывести на экран. Это связано с тем, что в режиме VGAна один пиксель выделено 4 бита видеопамяти (24=16).

Цвета палитры нумеруются от 0 до 15. Каждый цвет color[n] равен некоторому числу от 0 до 65. Чтобы выяснить, какие числа содержатся в цветах палитры, приведем небольшой код, который позволяет эти числа вывести на экран.

//структура для работы с палитрой

struct palettetype pal;

//переносим текущую палитру адаптера в структуру pal

getpalette(&pal);

//выводим состав палитры

for( int i=0; i<pal.size; i++)

printf("color[%2d]: %d", i, pal.colors[i]);

Результат приведем в следующей таблице.

Номер цвета

Содержание цвета

color[n]

Название цвета в палитре

0

00

BLACK

1

01

BLUE

2

02

GREEN

3

03

CYAN

4

04

RED

5

05

MAGENTA

6

20

BROWN

7

07

LIGHTGRAY

8

56

DARKGRAY

9

57

LIGHTBLUE

10

58

LIGHTGREEN

11

59

LIGHTCYAN

12

60

LIGHTRED

13

61

LIGHTMAGENTA

14

62

YELLOW

15

63

WHITE

Числа во второй колонке являются содержимым каждого из 16-ти цветов палитры. Эти числа одновременно являются номерами DACрегистров. Эти регистры являются регистрами цифро-аналогового преобразователя (digitaltoanalogconverter).

Имеется 256 регистров DAC, мы используем первые 64 регистраDAC. Каждый регистр содержит 18 бит, по 6-ти бит на красную, зеленую и синюю компоненты цвета.

Номера регистров

Биты красной компоненты

Биты зеленой компоненты

Биты синей компоненты

0

RRRRRR

GGGGGG

BBBBBB

1

RRRRRR

GGGGGG

BBBBBB

62

RRRRRR

GGGGGG

BBBBBB

63

RRRRRR

GGGGGG

BBBBBB

254

RRRRRR

GGGGGG

BBBBBB

255

RRRRRR

GGGGGG

BBBBBB

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

По умолчанию все регистры видеоадаптера заполнены определенными цветами. После включения пли перезагрузки компьютера в DAC-регистры записывается палитра цветов, хранящаяся в BIOS. Однако эти цвета можно изменить. В результате можно изменить палитру, заменив 16 стандартных цветов на 16 новых цветов.

Для подключения графического файла кDOSпрограмме, надо чтобы этот файл был подходящего формата. Наиболее просто подключить файл в форматеbmpс палитрой в 16 цветов.

Покажем, как можно получить графический файл нужного нам формата и bmp-файла другого формата. Пусть имеется картина корабля в файлеship_24.bmpследующего формата 102476824bbmp. На Рис.32. показано изображение, содержащееся в этом файле.

Рис. 32.

Корабль, формат файла 102478424bbmp.

Запускаем программу CorelPHOTO-PAINT. Открываем файл, содержащий изображение корабля. Выбираем пункты меню Image - Resamlpes an Image. В окнеResampleустанавливаем размер изображения в пикселях 640480. Выбираем пункты менюImage-Color Mode – Paletted (8-bit). В окнеConverttoPalettedустанавливаем следующие параметры.Smoothing – 0, Palette – Optimized, Dithering – Floyd-Steinberg, Dither Intensity – 100, Color –16. Сохраняем изображение в файлеship_16.bmp. Результат показан на Рис. 33.

Рис. 33.

Корабль, формат файла 64048016bmp.

Качество изображения конечно ухудшается. Это связано с тем, что теперь для рисования картины применяются только 16 цветов палитры.

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

Соответствующий код содержится в функции ViewBMP(), которую поместим в файлview.cpp. Прежде чем привести код этой функции скажем несколько слов о структуреbmp-файла.

В первых, 14 байтах файла содержатся поля структуры BITMAPFILEHEADER. Эта структура содержит информацию о типе, размере и плане bmp-файла.

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

В следующих 64 байтах файла содержится информация о 16 цветах палитры, по 4 байта на каждый цвет.

Далее расположен блок байт, в котором содержится изображение.

Поэтому алгоритм работы с bmp-файлом содержит следующие пункты.

1) Читаем графический bmp-файл.

2) Читаем заголовочные структуры BITMAPFILEHEADER, BITMAPINFOHEADER

3) Читаем состав палитры из 16 цветов в системе RGB.

4) Меняем палитру установленную по умолчанию в видеоадаптере на палитру, которая имеется в bmp-файле.

5) Выводим изображение на экран по одному пикселю.

Далее приводим код функции ViewBMP().

int ViewBMP(char* FileName)

{

//структура (14 байт) содержит информацию о типе, размере и плане файла,

//который содержит аппаратно-независимое растровое изображение

typedef struct tagBITMAPFILEHEADER {

unsigned int bfType; //тип файла - <BM>

unsigned long bfSize; //размер файла (B)

unsigned int bfReserved1;

unsigned int bfReserved2;

unsigned long bfOffBits; //смещение от начала файла до

} BITMAPFILEHEADER; //растрового изображения

//структура (40 байт) содержит информацию о размере, цветовом формате

//аппаратно-независимого растрового изображения

typedef struct tagBITMAPINFOHEADER{

unsigned long biSize; //размер структуры (B)

long biWidth; //ширина растрового изображения (pixel)

long biHeight; //высота растрового изображения (pixel)

unsigned int biPlanes;

unsigned int biBitCount;

unsigned long biCompression;

unsigned long biSizeImage;

long biXPelsPerMeter;

long biYPelsPerMeter;

unsigned long biClrUsed;

unsigned long biClrImportant;

} BITMAPINFOHEADER;

//структура относительные интенсивности red, green, blue цветов

typedef struct tagRGBQUAD {

unsigned char rgbBlue; //0 - 255

unsigned char rgbGreen;

unsigned char rgbRed;

unsigned char rgbReserved;

} RGBQUAD;

BITMAPFILEHEADER Head14;

BITMAPINFOHEADER Head40;

RGBQUAD HeadRGB[16]; //палитра из 16 цветов

FILE * fp;

fp = fopen(FileName,"rb");

if(fp==NULL)

return 0;

fread(&Head14, sizeof(Head14), 1, fp); //читаем структуру Head14

fread(&Head40, sizeof(Head40), 1, fp); //читаем структуру Head40

for(int i=0; i<16; i++) //читаем палитру

fread(&HeadRGB[i], sizeof(RGBQUAD), 1, fp);

long NPix, MPix;

NPix = Head40.biWidth;

MPix = Head40.biHeight;

//число байт содержащиеся в одной строчке растрового изображения

unsigned long NByt;

NByt = (Head14.bfSize - Head14.bfOffBits)/MPix;

//структура для работы с палитрой

struct palettetype pal;

//переносим текущую палитру адаптера в структуру pal

getpalette(&pal);

//устанавливаем палитру из файла bmp

//каждый цвет с номером <m> устанавливается в одном из регистров DAC

//имеется 256 регистров DAC

//мы используем первые 64 регистра DAC, а именно,

//берется регистр с номером pal.colors[m], и в его 18 бит

//заносится информация о красной(6 бит), зеленой(6 бит) и синей(6 бит)

//компонентах цвета с номером <m>

for (int m=0; m<16; m++)

setrgbpalette(pal.colors[m], 64*HeadRGB[m].rgbRed/256,

64*HeadRGB[m].rgbGreen/256, 64*HeadRGB[m].rgbBlue/256);

//устанавливаем указатель в файле на начало растрового изображения

fseek(fp,Head14.bfOffBits,SEEK_SET);

unsigned char Holder, b1, b2, bb;

int x = 0, y = 0;

//считываем пиксели растрового изображения и выводим на экран

for(int b = MPix; b >=0; b--)

{

for(int a = 1; a <= NByt; a++)

{

if(2*a <= NPix)

{

fread(&Holder, 1, 1, fp);

b1 = Holder>>4;

bb = Holder<<4;

b2 = bb>>4;

putpixel(2*a-2+x,b+y,b1);

putpixel(2*a-1+x,b+y,b2);

}

else

if((2*a > NPix) && (2*a-1 == NPix))

{

fread(&Holder, 1, 1, fp);

b1 = Holder>>4;

putpixel(2*a-2+x,b+y,b1);

}

else

fread(&Holder, 1, 1, fp);

}

}

fclose(fp);

return 1;

}

Теперь возьмем программу, содержащуюся в файле mov01DOS.cppи перепишем в файлmov07DOS.cpp. В заголовке добавим строчку.

#include "view.cpp"

В главной функции main() уберем строчку.

Land();

Добавим следующую строчку вызова функции ViewBMP().

ViewBMP("ship_16.bmp");

Компилируем, запускаем программу mov07DOS.exe, и результат работы этой программы показан на Рис.34.

Рис. 34.

Результат работы программы mov07DOS.cpp.

Соседние файлы в папке Lab_02