Сохранение и выдача изображений
Функция 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. ВЫВОД ТЕКСТА Описываемые ниже стандартные процедуры и функции поддерживают вывод текстовых сообщений в графическом режиме. Это не одно и то же, что использование процедур Write или WriteLn. Дело в том, что специально для графического режима разработаны процедуры, обеспечивающие вывод сообщений различными шрифтами в горизонтальном или вертикальном направлении, с изменением размеров и т.д. Однако в стандартных шрифтах, разработанных для этих целей фирмой Borland, отсутствует кириллица, что исключает вывод русскоязычных сообщений. С другой стороны, процедуры Write и WriteLn после загрузки в память второй половины таблицы знакогенератора (а эта операция легко реализуется в адаптерах EGA и VGA) способны выводить сообщения с использованием национального алфавита, но не обладают мощными возможностями специальных процедур. Ниже описываются стандартные средства модуля Graph для вывода текста. Процедура OutText. Выводит текстовую строку, начиная с текущего положения указателя. Заголовок: Procedure OutText(Txt: String); Здесь Txt - выводимая строка. При горизонтальном направлении вывода указатель смещается в конец выведенного текста, при вертикальном - не меняет своего положения. Строка выводится в соответствии с установленным стилем и выравниванием. Если текст выходит за границы экрана, то при использовании штриховых шрифтов он отсекается, а в случае стандартного шрифта не выводится. Процедура OutTextXY. Выводит строку, начиная с заданного места. Заголовок: Procedure OutTextXY (X,Y: Integer; Txt: String); Здесь X, Y - координаты точки вывода; Txt - выводимая строка. Отличается от процедуры OutText только координатами вывода. Указатель не меняет своего положения.
Процедура SetTextStyle. Устанавливает стиль текстового вывода на графический экран. Заголовок: Procedure SetTextStyle(Font,Direct,Size: Word); Здесь Font - код (номер) шрифта; Direct - код направления; Size - код размера шрифта. Для указания кода шрифта можно использовать следующие предварительно определенные константы: const DefaultFont = 0; {Точечный шрифт 8x8} TriplexFont = 1; {Утроенный шрифт TRIP.CHR} SmallFont = 2; {Уменьшенный шрифт LITT.CHR} SansSerifFont = 3; {Прямой шрифт SANS.CHR} GothicFont = 4; {Готический шрифт GOTH.CHR} Замечу, что эти константы определяют все шрифты для версий 4.0, 5.0, 5.5 и 6.0. В версии 7,0 набор шрифтов значительно расширен, однако для новых шрифтов не предусмотрены соответствующие мнемонические константы. В этой версии помимо перечисленных Вы можете при обращении к SetTextStyle использовать такие номера шрифтов:
Шрифт DefaultFont входит в модуль Graph и доступен в любой момент. Это -единственный матричный шрифт, т.е. его символы создаются из матриц 8x8 пикселей. Все остальные шрифты - векторные: их элементы формируются как совокупность векторов (штрихов), характеризующихся направлением и размером. Векторные шрифты отличаются более богатыми изобразительными возможностями, но главная их особенность заключается в легкости изменения размеров без существенного ухудшения качества изображения. Каждый из этих шрифтов размещается в отдельном дисковом файле. Если Вы собираетесь использовать какой-либо векторный шрифт, соответствующий файл должен находиться в Вашем каталоге, в противном случае вызов этого шрифта игнорируется и подключается стандартный. Замечу, что шрифт DefaultFont создается графическим драйвером в момент инициации графики на основании анализа текстового шрифта. Поэтому, если Ваш ПК способен выводить кириллицу в текстовом режиме, Вы сможете с помощью этого шрифта выводить русскоязычные сообщения и в графическом режиме. В остальных шрифтах эта возможность появляется только после их модификации.
Для задания направления выдачи текста можно использовать константы: const HorizDir = 0; {Слева направо} VertDir = 1; {Снизу вверх} Как видим, стандартные процедуры OutText и OutTextXY способны выводить сообщения лишь в двух возможных направлениях - слева направо или снизу вверх. Зная структуру векторных шрифтов, нетрудно построить собственные процедуры вывода, способные выводить сообщения в любом направлении. Каждый шрифт способен десятикратно изменять свои размеры. Размер выводимых символов кодируется параметром Size, который может иметь значение в диапазоне от 1 до 10 (точечный шрифт - в диапазоне от 1 до 32). Если значение параметра равно 0. устанавливается размер 1, если больше 10 - размер 10. Минимальный размер шрифта. при котором еще отчетливо различаются все его детали, равен 4 (для точечного шрифта - 1). Следующая программа демонстрирует различные шрифты. Их размер выбран так. чтобы строки имели приблизительно одинаковую высоту. Перед исполнением программы скопируйте все шрифтовые файлы с расширением.CHR в текущий каталог. Uses Graph, CRT; const FontNames: array [1..10] of String[4] = ('TRIP', 'LITT'' SANS ', ' GOTH ', 'SCRI ', ' SIMP ','TSCR ', ' LOOM ', ' EURO',' BOLD '); Tabl = 50; Tab2 = 150; Tab3 =220; var d, r, Err, {Переменные для инициации графики} Y,dY, {Ордината вывода и ее приращение} Size, {Размер символов} MaxFont, {Максимальный номер шрифта} k: Integer; {Номер шрифта} NT, SizeT, SynibT: String; {Строки вывода} c: Char; {-------------------} Procedure OutTextWithTab (S1, S2, S3, S4: String); {Выводит строки S1..S4 с учетом позиций табуляции Таb1..ТаbЗ} begin MoveTo((Tab1-TextWidth(Sl)) div2,Y); OutText (S1); MoveTo(Tabl+(Tab2-Tabl-TextWidth(S2)) div2,Y); OutText (S2); MoveTo(Tab2+(Tab3-Tab2-TextWidth(S3)) div 2,Y); OutText(S3); if S4='Symbols' then {Заголовок колонки Symbols} MoveTo((Tab3+GetMaxX-TextWidth(S4)) div 2,Y) else {Остальные строки} MoveTo(Tab3+3,Y); OutText(S4) end; {------------} begin {Инициируем графику} InitGraph(d,r, ' '); Err:= GraphResult; if ErrogrOk then WriteLn(GraphErrorMsg(Err)) else begin {Определяем количество шрифтов:} {$IFDEF VER70'} MaxFont:= 10;. {$ELSE} MaxFont:= 4; {$ENDIF} SetTextStyle(l,0,4); Y:= 0; OutTextWi thTab('N','Name',Size','Symbols'); {Определяем высоту Y линии заголовка} Y:= 4*TextHeight('Z') div3; Line(0,Y,GetMaxX,Y); {Определяем начало Y таблицы и высоту dY каждой строки} Y:= 3*TextHeight('Z') div 2; dY:= (GetMaxY-Y) div (MaxFont); {Готовим строку символов} SymbT:= ''; for с:= 'a' to 'z' do SymbT:= SymbT+c; {Цикл вывода строк таблицы} for k:= 1 to MaxFont do begin Size:= 0; {Увеличиваем размер до тех пор, пока высота строки не станет приблизительно равна dY} repeat inc(Size); SetTextStyle(k,0,Size+1); until (TextHeight('Z')>=dY) or (Size=10) or (Textwidth(FontNames[k])>(Tab2-Tab1)); {Готовим номер NT и размер SizeT шрифта}
Str(k,NT); Str(Size,SizeT); {Выводим строку таблицы} SetTextStyle(k,HorizDir,Size); OutTextWithTab(NT,FontNames[k],SizeT,SymbT); inc(Y,dY) end; {Рисуем линии рамки} Rectangle(0,0,GetMaxX,GetMaxY); Line(Tab1,0,Tabl,GetMaxY); Line(Tab2,0,Tab2,GetMaxY); Line(Tab3,0,ТаЬЗ,GetMaxY); {Ждем инициативы пользователя} ReadLn; CloseGraph end end. Процедура SetTextJustify. Задает выравнивание выводимого текста по отношению к текущему положению указателя или к заданным координатам. Заголовок: Procedure SetTextJustify(Horiz,Vert: Word); Здесь Horiz - горизонтальное выравнивание; Vert - вертикальное выравнивание. Выравнивание определяет как будет размещаться текст - левее или правее указанного места, выше, ниже или по центру. Здесь можно использовать такие константы: const LeftText = 0; {Указатель слева от текста} CenterText= 1; {Симметрично слева и справа,верху и снизу} RightText = 2; {Указатель справа от текста} BottomText= 0; {Указатель снизу от текста} TopText = 2; {Указатель сверху от текста} Обратите внимание на неудачные, с моей точки зрения, имена мнемонических констант: если, например, Вы зададите LeftText, что в переводе означает «Левый Текст», сообщение будет расположено справа от текущего положения указателя (при выводе процедурой OutTextXY - справа от заданных координат). Также «наоборот» трактуются и остальные константы. Следующая программа иллюстрирует различные способы выравнивания относительно центра графического экрана. Uses Graph, CRT; var d, r, e: Integer; begin {Инициируем графику} d:= Detect; InitGraph(d,, r, ' '); e:= GraphResult; if e <> grOk then WriteLn(GraphErrorMsg(e)) else begin {Выводим перекрестие линий в центре экрана} Line(0,GetMaxY div 2,GetMaxX,GetMaxY div 2); Line(GetMaxX div 2,0,GetMaxX div 2,GetMaxY); {Располагаем текст справа и сверху от центра} SetTextStyle(TriplexFont,HorizDir,3); SetTextJustify(LeftText,BottomText); OutTextXY (GetMaxX div 2, GetMaxY div 2, 'LeftText,BottomText'); {Располагаем текст слева и снизу} SetTextJustify (RightText, TopText); OutTextXY (GetMaxX div 2, GetMaxY div 2,'RightText, TopText'); if ReadKey=#0 then d:= ord(ReadKey); CloseGraph end end. Процедура SetUserCharSize. Изменяет размер выводимых символов в соответствии с заданными пропорциями. Заголовок: Procedure SetUserCharSize(XI,X2,Yl,Y2: Word); Здесь X1...Y2 - выражения типа Word, определяющие пропорции по горизонтали и вертикали. Процедура применяется только по отношению к векторным шрифтам. Пропорции задают масштабный коэффициент, показывающий во сколько раз увеличится ширина и высота выводимых символов по отношению к стандартно заданным значениям. Коэффициент по горизонтали находится как отношение X1 к Х2, по вертикали - как отношение Y1 к Y2. Чтобы, например, удвоить ширину символов, необходимо задать X1=2 и Х2=1. Стандартный размер символов устанавливается процедурой SetTextStyle, которая отменяет предшествующее ей обращение к SetUserCharSize. В следующем примере демонстрируется изменение пропорций уменьшенного шрифта. Uses Graph, CRT; var d, r, e: Integer; begin {Инициируем графику} d:= Detect;.InitGraph (d, r, ''); e:= GraphResult; if e <> grOk then WriteLn(GraphErrorMsg(e)) else begin MoveTo (0, GetMaxY div 2); SetTextStyle (SmallFont, HorizDir, 5); SetTextJustify (LeftText, BottomText); {Выводим сообщение стандартной высотой 5} OutText ('Normal Width,'); {Удваиваем ширину шрифта} SetUserCharSize (2, 1, 1, 1); OutText (' Double Width, '); {Удваиваем высоту, возвращаем стандартную ширину} SetUserCharSize (I, 1, 2, 1); OutText ('Double Height,'); SetUserCharSize (2, 1, 2, 1); OutText (' Double Width and Height'); if ReadKey=#0 then d:= ord(ReadKey); CloseGraph end end. Функция TextWidth. Возвращает длину в пикселях выводимой текстовой строки. Заголовок: Function TextWidth (Txjt: String): Word; Учитываются текущий стиль вывода и коэффициенты изменения размеров символов, заданные соответственно процедурами SetTextStyle и SetUserCharSize. Функция TextHeight. Возвращает высоту шрифта в пикселях. Заголовок: Function TextHeight(Txt: String): Word; Процедура GetTextSettings. Возвращает текущий стиль и выравнивание текста. Заголовок: Procedure GetTextSettins(var Textlnfo: TextSettingsType); Здесь Textlnfo - переменная типа TextSettingsType, который в модуле Graph определен следующим образом: type TextSettingsType = record Font: Word; {Номер шрифта} Direction: Word; {Направление} CharSize: Word; {Код размера} Horiz: Word; {Горизонтальное выравнивание} Vert: Word; {Вертикальное выравнивание} end; Функция InstallUserFont. Позволяет программе использовать нестандартный векторный шрифт. Заголовок функции: Function InstallUserFont(FileName: String): Integer; Здесь FileName - имя файла, содержащего векторный шрифт. Как уже говорилось, в стандартную поставку Турбо Паскаля версий 4.0 - 6.0 включены три векторных шрифта, для версии 7.0 - 10. Функция InstallUserFont позволяет расширить этот набор. Функция возвращает идентификационный номер нестандартного шрифта, который может использоваться при обращении к процедуре SetTextStyle. Функция InstallUserDriver. Включает нестандартный графический драйвер в систему BGI-драйверов. Заголовок функции: Function InstallUserDriver(FileName: String; AutoDetectPtr: Pointer): Integer; Здесь FileName - имя файла, содержащего программу драйвера; AutoDetectPtr - адрес точки входа в специальную процедуру автоопределения типа дисплея, которая в числе прочих процедур должна входить в состав драйвера. Эта функция расширяет и без того достаточно обширный набор стандартных графических драйверов и предназначена в основном для разработчиков аппаратных средств.
Читайте также: АВТОСОХРАНЕНИЕ ДОКУМЕНТА Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|