23374

Отображение графической информации в Delphi

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

Информатика, кибернетика и программирование

Объект Canvas Delphi имеет в своём распоряжении специальный объект который оформлен в виде свойства Canvas. Слово Canvas можно перевести на русский язык как холст для рисования или канва. Если у объекта есть свойство Canvas на его поверхности можно рисовать. Кроме компонентов перечисленных выше свойством Canvas обладают также: Image SpLitter ControlBox а так же объект TPrinter который благодаря этому свойству позволяет распечатывать графические изображения на принтере.

Русский

2013-08-04

112.5 KB

76 чел.

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

Отображение графической информации в Delphi.

Среда визуального программирования Delphi, как и Windows, поддержива-ет графический интерфейс пользователя (GDIGraphic Delphi Interface). Это значит, что все элементы, которые Вы видите на экране являются рисунками, включая текст. В Delphi существует два принципиально различных способа вывода графической информации:

  •  вывод заранее подготовленных изображений;
  •  рисование из программы.

Первый способ основан на использовании компонентов Image и Shape, с которыми Вы познакомились в предыдущей лабораторной работе. Вспомним так же и тот факт, что можно не только воспользоваться готовой картинкой или пиктограммой, но и создать их самостоятельно, используя Редактор Изображений Image Editor (см. лаб. раб. 3). Второй способ – это формирование изображений программным способом, к рассмотрению которого мы и переходим.

Объект Canvas

Delphi имеет в своём распоряжении специальный объект, который оформлен в виде свойства Canvas. Оно доступно только во время работы приложения, так что управлять им можно только из программы, написав нужный код на языке Object Pascal.

Слово «Canvas» можно перевести на русский язык как «холст» (для рисо-вания) или «канва». Если у объекта есть свойство Canvas, на его поверхности можно рисовать. Наиболее подходящими кандидатами на эту роль являются: сама форма и специальный компонент PaintBox, расположенный на странице System Палитры Компонентов.

Примечание. Кроме компонентов, перечисленных выше, свойством Canvas обладают также: Image, SpLitter, ControlBox, а так же объект TPrinter, который, благодаря этому свойству, позволяет распечатывать графические изображения на принтере.

Поверхность объекта, обладающего свойством Canvas, можно сравнить с воображаемым листом бумаги, на котором будет выполнен рисунок. Эту поверхность мы будем, далее, называть «область рисования».

При рисовании нужно помнить следующее:

  •  область рисования всегда совпадает с, так называемой, областью окна клиента (клиентской областью). Для формы ей является вся область формы, не включая заголовок, меню и рамку; для компонента PaintBox– вся поверхность объекта;
  •  все элементы изображения строятся из отдельных точек, называемых пикселями (Pixels), которые могут принимать на экране свой цвет;
  •  координаты области рисования по умолчанию устанавливаются таким образом, что точкой отсчёта (началом координат 0,0) является её верхний левый угол. Направление возрастания координат по оси Х: слева – направо, по оси У: сверху – вниз;
  •  по области  рисования, согласно установленным координатам, перемещается графический курсор (невидимый указатель текущей позиции), отмечающий положение активной точки для выполнения команд рисования;
  •  если по какой-то причине рисунок не вмещается в область рисования, он будет обрезан её границами;
  •  написание программного кода, связанного с рисованием (т.е. со свойст-вом Canvas), обычно осуществляется с помощью обработчика события OnPaint, доступного через Инспектор Объектов для используемого компонента.

Объект Canvas имеет пять главных свойств:

  •  Pen (Перо) –свойство для рисования линий и границ геометрических

           фигур. Перо следует командам графического курсора и, в свою

           очередь, имеет свои вложенные свойства:

  •  Color – определяет цвет линии (по умолчанию чёрный);
  •  Mode – стиль рисования (имеет множество значений, которые здесь не приводятся);
  •  Style – стиль линии, который может принимать значения:

                                        рsSolid – сплошная (по умолчанию);

                                        рsDosh – штриховая;

                                        рsDot – пунктирная;

                                       рsDoshDot – штрих пунктирная (и другие свойства);

  •  Widh – толщина линии (по умолчанию 1 пиксель);
  •  Brush (Кисть) – свойство для заполнения фигур, имеющие следующие

           вложенные свойства :

  •  Color – цвет кисти (по умолчанию – белый);
  •  Style – орнамент кисти, который может принимать значения:

                  bsClear – сплошная раскраска;

                  bsHorizontal – горизонтальные линии;

                  bsVertical – вертикальные линии;

                  bsFDiagonal – левые диагональные линии;

                 bsBDiagonal – правые диагональные линии;

                 bsCross – клетка;

                 bsDiagCross – косая клетка;

  •  Font (Шрифт) – свойство для вывода текста, имеющее следующие вло-

           женные свойства :

  •  Color – цвет символов;
  •  Height – высота шрифта в пикселях;
  •  Name – имя шрифта;
  •  Size – размер шрифта;
  •  Style –стиль шрифта, который может принимать следующие значения:

                      fsBold – полужирный;

                     fsItalic – курсив;

                    fsUnderline – подчёркнутый;

                    fsStrikeOut – перечёркнутый;

  •  PenPos (Позиция пера) –свойство для хранения текущей позиции рисо-

           вания (определяет положение пера  в области рисования в данный

           момент времени);

  •  Pixels [x,y: integer] –свойство-массив для записи и считывания коорди-

           нат отдельных точек области рисования («холста»).

Методы объекта Canvas 

(применяемые к области рисования):

MoveTo(x,y: integer) –перемещает перо с текущей позиции в точку с

           заданными координатами х, у без рисования линии;

LineTo(х.у: integer) -перемещает перо с текущей позиции в точку с задан-

           ными координатами х, у с прочерчиванием линии;

Arc(х1, у1, х2, у2, х3, у3, х4, у4: integer) –рисует дугу эллипса, вписанного

           в прямоугольник с координатами (х1,у1) и (х2,у2). Дуга определяет-

           ся радиусами эллипса, проходящими через точки (х3,у3) и (х4,у4);

Chord(х1, у1, х2, у2, х3, у3, х4, у4: integer) –рисует хорду эллипса по опи-

           санию, приведённому для метода Arc;

Ellipse(х1, у1, х2, у2: integer ) –рисует эллипс, вписанный в прямоуголь-

           ник с левым верхним углом в точке (х1, у1) и нижним правым

           углом в точке (х2, у2);

FillRect(Rect (х1, у1, х2, у2: integer)) – заполняет прямоугольник цветом,

           заданным в текущей кисти (Brush). Использует функцию Rect, кото-

           рая представляет прямоугольник с заданными координатами;

FloodFill(х,у : integer; Color: TColor; FillStyle: TFillStyle)заполнение те-

           кущим цветом, заданным в свойстве Brush:

           при FillStyle=fsBorder –замкнутой области от точки с координатами

           х, у до границы, определённой цветом Color;

           при FillStyle=fsSurface –тот участок поверхности, который имеет

           цвет Color;

Pie(х1, у1, х2, у2, х3, у3, х4, у4: integer) –рисует сектор эллипса, вписанно-

           го в прямоугольник с координатами (х1, у1) и (х2, у2). Сектор опре-

           деляется двумя радиусами эллипса, проходящими через точки

           (х3,у3) и (х4, у4);

Polyline (Points: array of TPoint) –рисует ломаную линию, последователь-

           но соединяя точки массива Points;

Polygon (Points: array of TPoint) –вычерчивает многоугольники, последо-

           вательно соединяя точки массива Рoints. Отличается от метода

           Polyline тем, что автоматически соединяет конец ломаной с её

           началом;

Rectangle (х1, у1, х2, у2: integer) –рисует прямоугольник с левым верхним

           углом в точке (х1, у1) и нижним правым углом в точке (х2,y2);

Retresh  –метод вызывается при необходимости перерисовки изображения;

RoundRect (х1, у1, х2, у2, х3, у3: integer) –рисует прямоугольник с закруг-

           лёнными углами. Углы рисуются как четверти эллипса с шириной

           х3 и высотой у3;

TextOut (х, у :integer, Text :String) –вывод текста, указанного в параметре

           Text. Текст вписывается в прямоугольник, верхний левый угол кото-

           рого имеет координаты х, у.

Примечание. Не следует забывать о том, что все действия производятся в соответствии с установками значений свойства Canvas ( установленных Вами или назначенных по умолчанию) до тех пор, пока они не будут изменены :

  •  Canvas.Pen –отвечает за вычерчивание линий и контуров геометрических фигур;
  •  Canvas.Brush –отвечает за  окраску областей;
  •  Canvas.Font –отвечает за вид шрифта выводимых сообщений.

Задание 1. Используя свойство Canvas формы, нарисуем праздничную

                  открытку.

Выполните следующие действия:

  •  отройте новый проект;
  •  форме дайте название «Графика в Delphi»;
  •  активизируйте событие OnPaint для формы в Инспекторе Объектов и впишите туда следующий код обработчика (все необходимые комментарии приведены прямо в тексте):

{============== Обработка события OnPaint для формы ==============}

procedure TForm1.FormPaint(Sender: TObject);

 var x,y :integer;              // Координаты вывода елки

     i :byte;                 // Параметр цикла

 begin

 Randomize;        // Установка неповторяющейся последовательности

                  // датчика случайных чисел

 with Form1.Canvas do

  begin

   Color:=clWhite;        // Установка цвета окна формы

   Pen.Style:=psSolid;    //Установка стиля линии

   Brush.Color:=clYellow; // Установка цвета кисти:

   Ellipse(ClientWidth-40,40,ClientWidth-80,80); //Луна

   Pen.Color:=clGreen;    // Установка цвета пера

   Pen.Width:=2;         // Установка ширины пера

   Brush.Color:=clGreen;  //Установка цвета кисти: цвет заливки фигур

   for i:=1 to 12 do     // Цикл рисования 12 елочек

    begin

      x:=Random(ClientWidth-30); //Выбор случайного числа x

     y:=Random(ClientHeight-30);//Выбор случайного числа y

      Polygon([Point(60+x, 10+y),Point( 90+x, 40+y),

               Point(70+x, 40+y),Point(100+x, 70+y),

               Point(70+x, 70+y),Point(110+x,110+y),

               Point(10+x,110+y),Point( 60+x, 60+y),

               Point(70+x, 70+y),Point( 20+x, 70+y),

               Point(60+x, 30+y),Point( 70+x, 40+y),

               Point(30+x,40+y)]);  //Елочка

    end;

  {------------------- Шрифт --------------------------}

   Font.Size:=20;                // Размер шрифта

   Font.Color:=clRed;             // Цвет шрифта

   Font.Name:='Arial';            // Название шрифта

   Font.Style:=[fsBold,fsItalic];//Стиль шрифта-полужирный курсив

   Brush.Color:=clAqua;        // Установка цвета кисти

   TextOut(10,10,'С новым годом!'); //Вывод надписи

   {------------------ Снежок -------------------------}

   For i:=1 to 250 do

     begin

      x:=Random(ClientWidth);

      y:=Random(ClientHeight);

      Pixels[x,y]:=clBlue;

     end;

  end

end;

        Примечание. В программе, приведенной выше использованы:

  •  функция Random(N), генерирующее случайное число из интервала от 0 до N–1;
  •  процедура RANDOMIZE, задающая разные последовательности случайных чисел;
  •  cвойства ClientWidth и ClientHeight – ширина и высота клиентской области окна формы.

  •  cохраните результаты Вашей работы и продемонстрируйте их преподавателю. У Вас должно получиться нечто, похожее на рис. 6.1.

Рис. 6.1. Вид праздничной открытки

Задание 2. Создайте на форме собственную поздравительную открытку с рисунком и подписью. (Подсказка: попробуйте нарисовать несколько разноцветных воздушных шаров, используя метод Ellipse).

Компонент PaintBox

Компонент PaintBox (Панель для рисования) расположен на странице System Палитры Компонентов. Его назначение – определить прямоугольную область для рисования внутри окна формы, то есть меньшее по размеру, тем самым оставив на форме место для размещения других компонентов. Следует отметить, что возможности рисования для компонентов PaintBox и Image совершенно одинаковы за исключением того, что последний «умеет» дополнительно выводить в свою область рисования готовые изображения (картинки, пиктограммы и метафайлы), о чём говорилось ранее, но не имеет события OnPaint.

Задание 3. Расположите на форме компоненты PaintBox и Button. Нарисуйте в PaintBox любое изображение. Пусть по нажатию кнопки оно перекрашивается в другой цвет.

Используем компонент PaintBox для создания приложения «Построение графиков функций». Данное приложение должно строить график любой заданной функции, иметь возможность его масштабировать и производить разметку осей координат.

Задание 4. Создание приложения «Построение графиков функций».

Выполните следующие действия :

  •  откройте новый проект;
  •  форме дайте название «Построение графиков функций);
  •  поместите на форму компонент PaintBox со страницы System Палитры Компонентов;
  •  поместите на форму три компонента Button, дав им соответственно названия: «Разметка осей», «Убрать разметку» и «Выход». Все компоненты размещайте согласно рис. 6.2.

Рис. 6.2. Вид окна «Построение графиков функций»

  •  активизируйте обработчик события OnPaint для компонента PaintBox и впишите туда нужный код;
  •  создайте обработчики событий для кнопок;
  •  сохраните проект в отдельной папке и поэкспериментируйте с ним. Постройте графики функций:  сos(х), tg(х), ctg(х), х^2, х^3, 1/х. Покажите результаты работы преподавателю.

Примечание. Построение графиков можно эффективно проводить с помощью специального компонента Chart со страницы Additional Палитры Компонентов, который будет рассмотрен в следующих лабораторных работах.

Ниже приводится текст модуля полностью с необходимыми комментариями. Разберитесь в нём и следуйте его указаниям для того, чтобы Ваше приложение заработало на компьютере.

Обратите внимание, что программа имеет собственную функцию F(х), где записана функция, которую требуется построить, и процедуру GRAFIK, где проводится непосредственное построение.

В обработчике события OnPaint производится построение осей координат и вызов процедуры GRAFIK.

Обработчик события для кнопки Разметка осей может вызвать наибольшие трудности. Обратите на него особое внимание и разберитесь как он работает. В нём используется собственная процедура RAZMETKA, задающая положение цифр на осях координат.

Обработчик события для кнопки Убрать разметку использует метод Refresh  (перерисовки изображения) для PaintBoxa.

unit Unit1;

interface

uses

 Windows, Messages, SysUtils, Classes, Graphics,

 Controls, Forms, Dialogs, StdCtrls, ExtCtrls;

type

 TForm1 = class(TForm)

   PaintBox1: TPaintBox;

   Button1: TButton;

   Button3: TButton;

   Button2: TButton;

   procedure Button1Click(Sender: TObject);

   procedure Button3Click(Sender: TObject);

   procedure Button2Click(Sender: TObject);

   procedure PaintBox1Paint(Sender: TObject);

 private

   { Private declarations }

 public

   { Public declarations }

 end;

 {------------------------------- Константы программы -----------------------------------}

const    H=30;          // Шаг разметки осей

       Dx=0.01;       // Шаг по аргументу

var

 Form1: TForm1;

 {----------------------------- Переменные программы -----------------------------------}

 x,y  : real;          // Аргумент и значение функции в точке х

 x0,y0: integer;       // Положение точки начала координат

 mx,my: real;          // Масштаб по осям X u Y

 A,B  : integer;       // Ширина и высота области вывода графика

 {------------------------------------------------------------------------------------------------}

implementation

{$R *.DFM}

{============== Функция, график которой надо построить ============}

function F(x:real):real;

begin

    F:=sin(x);

end;

{=================Построение графика ==========================}

procedure GRAFIK;

begin

 with Form1 do

  begin

{-------------------------------- Область вывода графика -----------------------------------}

     A:=PaintBox1.Width;         // Ширина области

     B:=PaintBox1.Height;        // Высота области

     my:=B/H*3.2;               // Масштаб по оси Y

     mx:=A/H*1.8;               // Масштаб по оси X

     x:=-A div 2;              // Начало изменения аргумента x

{---------------------------------- Построение графика --------------------------------------}

     repeat

     y:=F(x);

     PaintBox1.Canvas.Pixels[x0+Round(x*mx),y0-Round(y*my)]:=clRed;

     x:=x+Dx;                       {Шаг построения графика}

     until (x>=A div 2);

  end;

end;

{================= Событие ОnPaint для PaintBox'a =================}

procedure TForm1.PaintBox1Paint(Sender: TObject);

begin

{------------------------------- Вывод осей координат --------------------------------------}

 with PaintBox1,Canvas do

   begin

     x0:=Width  div 2;               //Положение точки начала

     y0:=Height div 2;               //      координат

     Brush.Color:=clWhite;           //Установка цвета кисти

     Rectangle(0,0,Width,Height);     //Рисуем прямоугольник

     Pen.Color:=clBlack;             //Установка цвета пера

     Pen.Style:=psSolid;             //Установка стиля линии

     MoveTo(x0,0);   LineTo(x0,Height); //Рисуем оси

     MoveTo(0,y0);   LineTo(Width,y0);

     Pixels[x0,y0]:=clRed;

     GRAFIK;                            //Вывод графика

   end;

end;

{=================== Кнопка <Разметка осей> ====================}

 procedure TForm1.Button1Click(Sender: TObject);

 var i :integer;

{---------------------------  Построение разметки графика -------------------------------}

 procedure Razmetka(xR,yR  :integer;//Координаты меток на осях

                 Nom    :String; //Число в виде текста

               Horizontal:Boolean); //Тип разметки

  begin

   with PaintBox1.Canvas do

    begin

     Brush.Color:=clWhite;         //Установка цвета кисти

     Ellipse(xR-3,yR-3,xR+3,yR+3); // Рисуем метки осей (точки)

{---------------------------------------- Шрифт -------------------------------------------------}

     Font.Name:='Baltica';         // Задание шрифта

     Font.Style:=[fsBold,fsItalic];     // Установка стиля шрифта -

                                                                              //        полужирный курсив

     Font.Size:=8;                                   // Установка размера шрифта

     Font.Color:=clBlue;        // Установка цвета шрифта

{---------------------------- Положение цифр на осях --------------------------------------}

     if Horizontal=true then

                        begin      // По горизонтальной оси

                         xR:=xR-TextWidth(Nom) div 2;

                         yR:=yR+4;

                        end

                  else  begin      // По вертикальной оси

                         xR:=xR+4;

                         yR:=yR-TextHeight(Nom) div 2;

                        end;

     TextOut(xR,yR,Nom);           // Вывод разметки осей

    end;

  end; {Конец процедуры Razmetka}

{---------------------------- Нанесение разметки осей --------------------------------------}

 begin

      For i:=-10 to 10 do           // Диапазон разметки осей

       if i=0 then Razmetka(x0+H*i,y0,IntToStr(i),True)

              else

              begin

             Razmetka(x0+H*i,y0,IntToStr(i),True);  {Ось X}

             Razmetka(x0,y0-H*i,IntToStr(i),False){Ось Y}

              end;

 end;

{================== Кнопка <Убрать разметку> ===================}

procedure TForm1.Button2Click(Sender: TObject);

begin

 PaintBox1.Refresh

 end;

{================== Кнопка <ВЫХОД> =========================}

procedure TForm1.Button3Click(Sender: TObject);

 begin

 Close;

 end;

end.

Задание для самостоятельной работы

Данная программа имеет ряд недостатков:

  •  нельзя задать диапазоны изменения аргумента и шаг;
  •  нельзя выбрать новую функцию для построения графика из работающей программы;
  •  масштаб задаётся “вручную”, установкой в тексте программы соответствующих коэффициентов mx и my.

Попробуйте устранить эти недостатки. Это будет хорошим упражнением по программированию.

Вопросы

  1.  Какие способы вывода графической информации существуют в Delphi ? В чём их отличие ?
  2.  На каких компонентах Delphi позволяет выводить графические изображения (рисовать)?
  3.  Что такое область рисования, каким свойством она задаётся и какие особенности имеет ?
  4.  Перечислите основные свойства объекта Canvas.
  5.  Перечислите методы, которые использует Canvas в процессе построения графических изображений. Какой метод позволяет выводить надписи? Перерисовать изображение?
  6.  Как, используя свойство Canvas нарисовать прямую линию?
  7.  Можно ли менять шрифт надписей в ходе выполнения программы? Если можно, то как?
  8.  Каким образом можно сделать надпись на форме?
  9.  В чём разница между формой, компонентами Image и PаintBox при работе с графическими изображениями?
  10.  Как Вы думаете, по какой причине приложение «Построение графиков функции» не может построить график у=ехр(х)? А график у=sqrt(x)?      Что нужно предпринять, чтобы устранить эти недостатки?

Резюме

  1.  В Delphi существуют два способа вывода графической информации:
  •  вывод заранее подготовленных изображений с помощью компонентов Image и Shape;
  •  рисование из программы только во время работы приложения. Это позволяют сделать компоненты, обладающие свойством Canvas: сама форма, PaintBox, Image и ряд других.
  1.  Для построения графических изображений свойство Canvas обладает набором собственных вложенных свойств и методов.
  2.  С помощью свойства Canvas можно осуществить вывод графической информации не только на экран, но и на принтер, используя объект TPrinter.
  3.  Компонент PaintBox позволяет выделить на форме место для рисования меньшее, чем окно формы, тем самым оставив на последнем место для размещения других компонентов.

12

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