Сохранение и выдача изображений

Функция ImageSize.

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

Function ImageSize(X1,Y1,X2,Y2: Integer): Word;

Здесь X1... Y2 - координаты левого верхнего (X1, Y1) и правого нижнего (Х2, Y2) углов фрагмента изображения.

Процедура Getlmage.

Помещает в память копию прямоугольного фрагмента изображения. Заголовок:

Procedure Getlmage(X1,Y1,X2,Y2: Integer; var Buf)

Здесь X1...Y2 - координаты углов фрагмента изображения; Buf - переменная или участок кучи, куда будет помещена копия видеопамяти с фрагментом изображения.

Размер Buf должен быть не меньше значения, возвращаемого функцией ImageSize с теми же координатами X1....Y2.

Процедура Put Image.

Выводит в заданное место экрана копию фрагмента изображения, ранее помещенную в память процедурой Getlmage. Заголовок:

Procedure Putlmage(X,Y: Integer; var Buf; Mode: Word);

Здесь X,Y- координаты левого верхнего угла того места на экране, куда будет скопирован фрагмент изображения; Buf - переменная или участок кучи, откуда берется изображение; Mode - способ копирования.

Как видим, координаты правого нижнего угла не указываются, так как они полностью определяются размерами вновь выводимой на экран копии изображения. Координаты левого верхнего угла могут быть какими угодно, лишь бы только выводимая копия уместилась в пределах экрана (если копия не может разместиться на экране, она не выводится и экран остается без изменений).

Параметр Mode определяет способ взаимодействия вновь размещаемой копии с уже имеющимся на экране изображением. Взаимодействие осуществляется путем применения кодируемых этим параметром логических операций к каждому биту копии и изображения. Для указания применяемой логической операции можно использовать одну из следующих предварительно определенных констант:

const

NormalPut= 0;{Замена существующего изображения на копию}

XorPut = 1;{Исключительное ИЛИ}

OrPut = 2;{Объединительное ИЛИ}

AndPut = 3;{Логическое И} 

NotPut = 4;{Инверсия изображения}

Наиболее часто используются операции NormalPut, XORPut и NotPut. Первая из них просто стирает часть экрана и на это место помещает копию из памяти в том виде, как она там сохраняется. Операция NotPut делает то же самое, но копия выводится в инверсном виде. Для монохромного режима это означает замену светящихся пикселей на темные и наоборот. В цветном режиме операция NotPut применяется к коду цвета каждого пикселя. Например, для White (код 15 или в двоичном виде 1111) эта операция даст код 0000 = 0 = Black, для Red = 4 = 0100 получим 1011 = 11 = LightCyan и т.д. Операция XORPut, примененная к тому же месту экрана, откуда была получена копия, сотрет эту часть экрана. Если операцию применить дважды к одному и тому же участку, вид изображения на экране не изменится. Таким способом можно довольно просто перемещать изображения по экрану, создавая иллюзию движения.

Следующая программа рисует «Неопознанный Летающий Объект» - летающую тарелку на звездном фоне (рис. 14.10).

Рис.14.10. Иллюстрация процедур Getlmage/Putlmage

Uses Graph, CRT; 

const

r = 20; {Характерный размер НЛО} 

pause = 50; {Длительность паузы} 

var

d,m,e,xm/ym,x,y/lx,ly,rx,ry,

Size,i,dx,dy,Width,Height: Integer; 

Saucer : Pointer; 

label

loop; 

begin

{Инициируем графику} 

d := Detect; lnitGraph(d, m, ' ') ; 

e := GraphResult; if e <> grOk then

WriteLn(GraphErrorMsg(e)) 

else 

begin

x := r*5;

у := r*2;

xm := GetMaxX div 4;

ym := GetMaxY div 4;

{Создаем "тарелку" из двух эллипсов с усами антенн}

Ellipse (х,у,0,360,r,r div 3+2); ,

Ellipse (х,у-4,190,357,r,r div 3);

Line (х+7,у-б,х+10,у-12);

Line (x-7,y-6, х-10, у-12);

Circle (x+10,y-12,2);

Circle (х-10,у-12,2);

FloodFill(x+l,y+4,White);

{Определяем габариты НЛО и помещаем его в кучу}

1х := х-r-1;

1у := у-14;

гх := х+r+1;

гу := у+r div 3+3;

Width := rx - lx + 1;

Height:= ry - ly + 1;

Size := ImageSize(lx, ly, rx, ry);

GetMem (Saucer, Size);

Getlmage (lx, ly, rx, ry, Saucer^);

{Стираем построенное}

Putlmage (lx, ly, Saucer^, xorPut);

{Создаем звездное небо}

Rectangle(xm,ym,3 *xm,3 *ym);

SetViewPort(xm+1,ym+1,3*xm-1,3*ym-1,ClipOn);

xm := 2*xm;

ym := 2*ym;

for i:=1 to 200 do

PutPixe1 (Random(xm), Random(ym), White) ;

{Задаем начальное положение НЛО и направление движения}

х := xm div 2;

у := ym div 2;

dx := 10;

dy := 10;

{Основной цикл}

repeat

Putlmage(x,y,Saucer^,xorPut); {Изображаем НЛО на} 

Delay(pause); {новом месте и после} 

Putlmage (x, у, Saucer^, XorPut);{паузы стираем его} 

{Получаем новые координаты} 

loop: x := x+dx;

у := y+dy; 

{НЛО достиг границы экрана?} 

if (x<0) or (x+Width+1>xm) or 

(у<0) or (y+Height+1>ym) then 

begin {Да - НЛО достиг границы: меняем направление его перемещения} 

x := x-dx; 

y:= y-dy;

dx : = GetMaxX div 10 - Random(GetMaxX div 5); 

dy := GetMaxY div 30 - Random(GetMaxY div 15); 

goto loop 

end

until KeyPressed;

if ReadKey=#0 then x := ord(ReadKey); 

CloseGraph 

end 

end.