- •Московский институт электронной техники
- •!!!! Замечание.
- •Введение.
- •Графические вставки из bmp-файлов в dos программах.
- •Графические вставки из bmp-файлов в win программах.
- •Графические вставки из bmp-файлов в dos программах в режиме работы с видеостраницами.
- •Графические вставки из bmp-файлов в win программах в режиме работы с оперативной памятью.
- •Перемещение по экрану графических вставок из bmp-файлов в dos программах.
- •Перемещение по экрану графических вставок из bmp-файлов в win программах. Использование двух контекстов памяти.
- •Использование набора bmp-файлов для создания эффекта движения. Чтение bmp-файлов из ресурсов программы.
- •Использование набора bmp-файлов для создания эффекта движения. Загрузка bmp-файлов в контекст памяти.
- •Задание к выполнению работы.
Московский институт электронной техники
Кафедра ИПОВС
Лабораторная работа 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следующего формата 102476824bbmp. На Рис.32. показано изображение, содержащееся в этом файле.
Рис. 32.
Корабль, формат файла 102478424bbmp.
Запускаем программу CorelPHOTO-PAINT. Открываем файл, содержащий изображение корабля. Выбираем пункты меню Image - Resamlpes an Image. В окнеResampleустанавливаем размер изображения в пикселях 640480. Выбираем пункты менюImage-Color Mode – Paletted (8-bit). В окнеConverttoPalettedустанавливаем следующие параметры.Smoothing – 0, Palette – Optimized, Dithering – Floyd-Steinberg, Dither Intensity – 100, Color –16. Сохраняем изображение в файлеship_16.bmp. Результат показан на Рис. 33.
Рис. 33.
Корабль, формат файла 64048016bmp.
Качество изображения конечно ухудшается. Это связано с тем, что теперь для рисования картины применяются только 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.