Язык программирования Pascal
Введение
Язык программирования Pascal является универсальным языком высокого уровня. Паскаль используется для программирования почти всех типов задач на почти всех типах ЭВМ и в настоящее время считается одним из лучших языков программирования высокого уровня. Кроме того, его простота позволяет применять эту систему программирования для обучения.
В настоящее время Pascal вытеснила более современная и мощная система программирования Borland Delphi, которая предлагает пользователю неограниченные возможности для написания Windows-программ любой сложности. Delphi продолжает традиции Pascal, и основана на языке Object Pascal. Тем не менее, Pascal остается самой распространённой оболочкой программирования для MS-DOS. С помощью языка Pascal я попытался написать программу для просмотра и записи 8-битных BMP файлов. В данной программе написаны два модуля, в которых описаны основные процедуры и функции, позволяющие просматривать BMP файл, а также возможность рисовать свою картинку, сохраняя её в BMP файл.
1. Графические BMP файлы
С форматом BMP работает огромное
количество программ, так как его
поддержка интегрирована в
2. Структура BMP файла.
BMP-файл состоит из четырёх частей:
- Заголовок файла (TBitmapFileHeader)
- Заголовок изображения (TBitmapInfoHeader, может отсутствовать).
- Палитра (может отсутствовать)
- Само изображение
Информационный заголовок файла можно представить как запись с полями организованными следующим образом:
TBitmapFileHeader=record
bfType: word; {всегда ′BM′ или hex $4D42}
bfSize: longword; {физический размер файла в байтах}
bfReserved1, {всегда 0}
bfReserved2: word; {всегда 0}
bfOffBits: LongWord; {содержит смещение в байтах от начала структуры TBitmapFileHeader до непосредственно битов изображения.}
end;
Используя этот заголовок можно определить, является ли считанный файл BMP-файлом. Информационный заголовок изображения организован следующим образом:
TBitMapInfoHeader = record
biSize: LongWord;{размер структуры в байтах,всегда 40 байт.}
biWidth: LongInt; { ширина изображения в пикселах.}
biHeight: LongInt; { высота изображения в пикселах.}
biPlanes: Word; { содержит единицу.}
biBitCount: Word; { указывает количество бит на пиксел.}
biCompression: LongWord;{метод сжатия}
biSizeImage: LongWord;{ Указывает размер изображения в байтах.}
biXPelsPerMeter: LongInt; { горизонтальное разрешение в пикселах на метр}
biYPelsPerMeter: LongInt; { вертикальное разрешение в пикселах на метр}
biClrUsed: LongWord;{ количество используемых цветовых индексов в палитре.}
biClrImportant: LongWord;{ указывает количество индексов, необходимых для отображения изображения. Если содержит ноль — все индексы одинаково важны}
end;
Палитра может содержать
TRGBQuad = record
rgbBlue: Byte;
rgbGreen: Byte;
rgbRed: Byte;
rgbReserved: Byte; end;
TBMPalette = array[0..255] of TRGBQuad;
Схема кодирования цвета
здесь отличается от стандартной RGB
схемы последовательностью
После таблицы цветов находятся данные изображения (битовая карта), которое по строкам растра записано снизу вверх, а внутри строки — слева направо. Так как на некоторых платформах невозможно считать единицу данных, которая меньше 4 байт, длина каждой строки выровнена на границу в 4 байта, т.е. при длине строки, некратной четырем, она дополняется нулевыми байтами.
3. Описание программы
Процедуры и функции, описанные в модуле AbitMap:
function ValidBitMapImage(filename: string): boolean;
procedure ReadBitMapHeader(var A: file;
var MF: TBitMapFileHeader;
var BF: TBitMapInfoHeader;
var P: TBMPalette);
procedure SetBMPPalette(MF: TBitMapInfoHeader; P: TBMPalette);
procedure Draw8BitImage(var A: file;
BF: TBitMapInfoHeader);
Функция ValidBitMapImage - возвращает true, если открываемый файл является bmp-файлом, иначе возвращает false. С помощью процедуры BlockRead(F,h,SizeOf(h)) читает из начала файла два байта, в переменную h типа word. Если h=$4D42, т. е. в заголовке файла записан идентификатор BMP файла ‘BM’, то функция возвращает значение true.
function ValidBitMapImage(filename: string): boolean;
var
F: file;
h: Word;
begin
ValidBitMapImage:=false;
assign(F,filename);
{$I-}
reset(F,1);
{$I+}
if ioresult<>0 then
ValidBitMapImage:=false
else
begin
BlockRead(F,h,SizeOf(h));
if h=$4D42 then
ValidBitMapImage:=true;
end;
Close(F);
end; Процедура ReadBitMapHeader – считывает заголовок файла и изображения, а также сохраняет в массиве TBMPalette цвета считываемого изображения.
procedure ReadBitMapHeader(var A: file;
var MF: TBitMapFileHeader;
var BF: TBitMapInfoHeader;
var P: TBMPalette);
var
i,n,l: word;
begin
BlockRead(A, MF.bfType, SizeOf(MF.bfType));
BlockRead(A, MF.bfSize, SizeOf(MF.bfSize));
BlockRead(A, MF.bfReserved1, SizeOf(MF.bfReserved1));
BlockRead(A, MF.bfReserved2, SizeOf(MF.bfReserved2));
BlockRead(A, MF.bfOffBits, SizeOf(MF.bfOffBits));
BlockRead(A, BF.biSize, SizeOf(BF.biSize));
BlockRead(A, BF.biWidth, SizeOf(BF.biWidth));
BlockRead(A, BF.biHeight, SizeOf(BF.biHeight));
BlockRead(A, BF.biPlanes, SizeOf(BF.biPlanes));
BlockRead(A, BF.biBitCount, SizeOf(BF.biBitCount));
BlockRead(A, BF.biCompression, SizeOf(BF.biCompression));
BlockRead(A, BF.biSizeImage, SizeOf(BF.biSizeImage));
BlockRead(A, BF.biXPelsPerMeter, SizeOf(BF.biXPelsPerMeter));
BlockRead(A, BF.biYPelsPerMeter, SizeOf(BF.biYPelsPerMeter));
BlockRead(A, BF.biClrUsed, SizeOf(BF.biClrUsed));
BlockRead(A, BF.biClrImportant, SizeOf(BF.biClrImportant));
for i:=0 to 255 do
begin
BlockRead(A, P[i].rgbBlue,SizeOf(P[i].
BlockRead(A, P[i].rgbGreen,SizeOf(P[i].
BlockRead(A, P[i].rgbRed,SizeOf(P[i].
BlockRead(A, P[i].rgbReserved,SizeOf(P[i].
end;
end;
Процедура SetBMPPalette – переопределяет стандартную палитру Паскаля в палитру BMP изображения.
procedure SetBMPPalette(MF: TBitMapInfoHeader; P: TBMPalette);
var
n,i: word;
begin
for i:=0 to 255 do
SetRGBPalette(i,P[i].rgbRed,P[
end;
Процедура Draw8BitImage – выводит на экран просматриваемое изображение. Происходит проверка что длина каждой строки кратна 4. Если это не так то дописываем недостающие байты si:=BF.biWidth+(4-(BF.biWidth mod 4)).
procedure Draw8BitImage(var A: file;
BF: TBitMapInfoHeader);
var
i,j,si: word;
c: byte;
begin
ClearDevice;
if BF.biWidth mod 4=0 then
si:=BF.biWidth
else
si:=BF.biWidth+(4-(BF.biWidth mod 4));
for j:=BF.biHeight downto 1 do
for i:=1 to si do
begin
BlockRead(A,c,SizeOf(c));
if j<=BF.biWidth then
PutPixel(i,j,c);
end;
end;
Процедура описанная в модуле APaint: procedure Save8BitImage(var F: file;x,y,w,h: integer);
Процедура Save8BitImage – сохраняет изображение в BMP файл. Процедура GetPalette(PD) возвращает значение стандартной палитры, а потом она сохраняется в массив Р, в ту палитру, которую запишем в BMP файл.В файл записываются значения заголовков файла и изображения, записывается палитра, а потом записывается и само изображение.
procedure Save8BitImage(var F: file;x,y,w,h: integer);
var
FH: TBitMapFileHeader;
IH: TBitMapInfoHeader;
P: TBMPalette;
PD: PaletteType;
i,j,l: word;
c: Byte;
begin
GetPalette(PD);
for i:=0 to 255 do
begin
P[i].rgbRed:=PD.Colors[i].Red;
P[i].rgbGreen:=PD.Colors[i].
P[i].rgbBlue:=PD.Colors[i].
P[i].rgbReserved:=0;
end;
if w mod 4=0 then
l:=0
else
l:=4-(w mod 4);
FH.bfType:=19778;
FH.bfSize:=14+40+(4*256)+((w+
FH.bfReserved1:=0;
FH.bfReserved2:=0;
FH.bfOffBits:=14+40+(4*256);
IH.biSize:=40;
IH.biWidth:=w;
IH.biHeight:=h;
IH.biPlanes:=1;
IH.biBitCount:=8;
IH.biCompression:=0;
IH.biSizeImage:=(w+l)*h;
IH.biXPelsPerMeter:=0;
IH.biYPelsPerMeter:=0;
IH.biClrUsed:=0;
IH.biClrImportant:=0;
BlockWrite(F,FH.bfType,2);
BlockWrite(F,FH.bfSize,4);
BlockWrite(F,FH.bfReserved1,2)
BlockWrite(F,FH.bfReserved2,2)
BlockWrite(F,FH.bfOffBits,4);
BlockWrite(F,IH.biSize,4);
BlockWrite(F,IH.biWidth,4);
BlockWrite(F,IH.biHeight,4);
BlockWrite(F,IH.biPlanes,2);;
BlockWrite(F,IH.biBitCount,2);
BlockWrite(F,IH.biCompression,
BlockWrite(F,IH.biSizeImage,4)
BlockWrite(F,IH.
BlockWrite(F,IH.
BlockWrite(F,IH.biClrUsed,4);
BlockWrite(F,IH.
for i:=0 to 255 do
begin
BlockWrite(F,P[i].rgbBlue,1);
BlockWrite(F,P[i].rgbGreen,1);
BlockWrite(F,P[i].rgbRed,1);
BlockWrite(F,P[i].rgbReserved,
end;
for j:=h downto 1 do
for i:=1 to w+l do
begin
c:=0;
if i<=w then
c:=GetPixel(x+i-1,y+j-1);
BlockWrite(F,c,SizeOf(c));
end;
end;
Заключение
В данной курсовой работе я написал программу и два модуля обеспечивающие вывод на экран BMP файла, и сохранение нарисованного изображения в BMP файл. В итоге я приобрел опыт разработки и написания сложный программ в среде Free Pascal.
Руководство пользователя
1. Запустите программу. 2. В появившемся окне: А) для просмотра BMP файла выберите пункт 1 «Просмотр файла»: в появившемся окне введите имя BMP файла и нажмите Enter. Для выхода в главное меню нажмите любую клавишу; Б) для рисования пункт 2 «Рисование»: 1)чтобы передвигать курсор воспользуйтесь клавишами W,S,A,D; 2)чтобы поставить точку нажмите «пробел», чтобы провести линию передвиньте курсор в нужное место и нажмите Enter; 3)для выбора цвета нажать R : красный, G : зеленый, B : синий; 4)для сохранения изображения нажмите F2, введите имя файла, задайте высоту и ширину изображения, нажмите Enter. Для выхода нажмите Esc. В)для выхода из программы выбрать пункт 3 “Выход”.
Список используемых источников
1. Фаронов В.В. Турбо
Паскаль 7.0. Учебный курс: учебное
пособие / В.В. Фаронов. – М.:Кнорус,
2009. – 368с. 2. Кетков Ю., Кетков А.
Свободное программное обеспечение Free
Pascal для студентов и школьников. 3. Немнюгин
С.А. Турбо Паскаль Программирование на
языке высокого уровня. 4. BMP file[Электронный
ресурс] – Электрон. текстовые дан. –
Режим доступа: http://ru.wikipedia.org/wiki/