Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Рисование с помощью пера PenСодержание книги
Поиск на нашем сайте
У канвы имеется свойство Реn — перо. Это объект, в свою очередь, имеющий ряд свойств. Свойство Style определяет вид линии. Все стили со штрихами и пунктирами доступны только при Width = 1. В противном случае линии этих стилей рисуются как сплошные. Стиль psInsideFrame — единственный, который допускает произвольные цвета. Цвет линии при остальных стилях округляется до ближайшего из палитры Windows. У канвы имеется свойство PenPos типа TPoint. Это свойство определяет в координатах канвы текущую позицию пера. Перемещение пера без прорисовки линии, т.е. изменение PenPos, производится методом канвы MoveTo(X,Y). Здесь X и Y — координаты точки, в которую перемещается перо. Эта текущая точка становится исходной, от которой методом LineTo(X,Y) можно провести линию в точку с координатами (X,Y). При этом текущая точка перемещается в конечную точку линии и новый вызов LineTo будет проводить линию из этой новой текущей точки. Давайте попробуем нарисовать пером график синуса из предыдущего примера. Откройте прежний проект, добавьте на него еще один компонент. Размеры обоих компонентов Image должны быть абсолютно одинаковы, так как на этом для экономии размера кода и вашего труда основана программа, которую мы напишем. Затем в уже написанный вами обработчик щелчка на кнопке добавьте перед началом цикла оператор Image2.Canvas.MoveTo(0,Image2.Height div 2); который переводит перо в начало координат второго графика — на левый край канвы в середину ее высоты. А перед заключительным end цикла добавьте оператор Image2.Canvas.LineTo(PX, PY); который рисует на втором графике линию, соединяющую соседние точки. Для экономии кода мы воспользовались тем, что оба графика у нас абсолютно одинакового размера и, следовательно, пересчет координат достаточно провести для одного из них, а потом воспользоваться этими координатами для рисования обоих графиков. Cравните полученные графики. Отметим еще одно ценное свойство компонента Image и его канвы. Вы можете задавать координаты пикселей, выходящие за пределы размеров канвы, и ничего страшного при этом не случится. Это позволяет не заботиться о том, какая часть рисунка попадает в рамку Image, а какая нет. Вы можете легко проверить это, увеличив, например, вдвое размах вашей синусоиды. Попробуйте сделать это самостоятельно.
Это позволяет легко осуществлять приложения, в которых пользователю предоставляется возможность увеличивать и просматривать в деталях какие-то фрагменты графиков. Перо может рисовать не только прямые линии, но и фигуры. Ниже перечислены некоторые из методов канвы, использующие перо для рисования фигур: Arc - Рисует дугу окружности или эллипса Chord - Рисует замкнутую фигуру, ограниченную дугой окружности или эллипса и хордой Pie - Рисует сектор окружности или эллипса PolyBezier - Рисует кусочную кривую третьего порядка Polygon - Рисует замкнутую фигуру с кусочно-линейной границей Polyline - Рисует кусочно-линейную кривую Rectangle - Рисует прямоугольник RoundRect - Рисует прямоугольник со скругленными углами Ниже приведен текст процедуры, которая рисовала некоторые фигуры, приведенные в вышележащей таблице. with Imagel.Canvas do begin Font.Style:= [fsBold]; Arc(10,10,90,90,90,50,10,50); TextOut(40,60,'Arc'); Chord(110,10,190,90,190,50,110,50); TextOut (135,60, 'Chord'); Ellipse (210,10,290,50); TextOut(230,60,'Ellipse'); end.
Brush — кисть
У канвы имеется свойство Brush — кисть. Это свойство определяет фон и заполнение замкнутых фигур на канве. Brush — это объект, имеющий, в свою очередь ряд свойств. Свойство Color определяет цвет заполнения. Свойство Style определяет шаблон заполнения (штриховку). Имеется еще одно свойство кисти — BitMap, определяющее нестандартное заполнение заданным шаблоном. Шаблон задается битовой матрицей размером 8 на 8. Если для кисти задан шаблон BitMap, то заполнение производится именно этим шаблоном, независимо от значения свойства Style. Шаблон BitMap может создаваться в процессе выполнения приложения или, например, загружаться из файла, как в приведенном ниже примере: Bitmap: TBitmap; begin Bitmap:= TBitmap.Create; try Bitmap.LoadFromFile('MyBitmap.bmp'); Forml.Canvas.Brush.Bitmap:= Bitmap; finally Imagel.Canvas.Brush.Bitmap:= nil; Bitmap.Free; end; end; В этом примере создается объект Bitmap типа TBitmap, и в него загружается битовая матрица из файла с именем MyBitmap.bmp. Затем свойству Imagel.Canvas.Brush.Bitmap присваивается указатель на этот объект. После этого загруженный шаблон можно использовать для заполнения фигур на канве Imagel. В конце кода свойству BitMap присваивается значение nil, после чего заполнение опять начинает определяться свойством Style. Затем объект Bitmap уничтожается, чтобы освободить занимаемую им память.
Имеются функции канвы, рисующие заполненные фигуры. Это, например, метод FillRect, объявленный как procedure FillRect(const Rect: TRect); Он заполняет заданным стилем или шаблоном прямоугольную область, заданную параметром Rect. Этот параметр имеет тип TRect. Для его задания проще всего использовать функцию Rect(Xl,Yl,X2,Y2), возвращающую структуру Rect с координатами углов, заданных параметрами (XI, Y1) и (Х2, Y2). Функцию FillRect удобно, в частности, использовать для стирания изображения. Например, оператор with Imagel do Canvas.FillRect(Rect(0,0,Width,Height)); очищает всю площадь канвы компонента Imagel. Кисть участвует в заполнении фигур не только с помощью этой функции. Все перечисленные ранее методы рисования замкнутых фигур тоже заполняют их с по мощью кисти. Это относится к методам Chord, Ellipse, Pie, Polygon и др. Имеется еще один интересный метод, работающий с кистью. Это метод Flood Fill, который заполняет замкнутую область на канве. Для определения области закрашивания можно использовать координаты и цвет одного из пикселей, расположенных внутри области (если FillStyle = fsSurfaсе) или снаружи ее (если FillStyle = fsBorder).
Пример построения собственного простого графического редактора
Давайте попробуем использовать полученные нами сведения для построения собственного простенького графического редактора, воспроизводящего некоторые функции настоящих редакторов. 1. Начните новое приложение. 2. Перенесите на форму два компонента типа Tlmage и расположите их в нижней левой части формы, придав квадратную форму, например, размером 20 на 20. Это будут окна основного и вспомогательного цветов. Имена этих компонентов будут Imagel и Image2. (рис. 11)
Рисунок 11. Графический редактор, работа с изображением, загруженным из файла #' Г Рафический редактор 3. Перенесите на форму еще один компонент типа Tlmage и расположите его в верхней части формы, несколько отступив от левого края, где у нас будет инструментальная панель, и растянув так, чтобы он занимал основную часть формы. Это будет холст для картинок. Имя этого компонента будет ImageS. 4. Перенесите на форму еще один компонент типа TImage и расположите его внизу правее первых двух на одном с ними уровне. Это будет палитра цветов. Ее высоту задайте той же, что у первых двух компонентов, а длину — в 10 раз большую. Имя этого компонента будет Image4. 5. Перенесите на форму кнопку типа TSpeedButton и расположите ее в верхнем левом углу формы. Эта кнопка будет соответствовать кисти — типичному инструменту графических редакторов. Назовите ее SBBrush. Установите у кнопки свойство Grouplndex равным 1 и свойство AllowAHUp в true. Эти свойства обеспечат кнопке возможность фиксироваться в нажатом и не нажатом состоянии. Желательно загрузить в свойство Glyph пиктограмму кисти (файл..\lma-ges\Buttons\brush.bmp). 6. Перенесите на форму еще одну кнопку типа TSpeedButton и расположите ее ниже SBBrush. Эта кнопка будет соответствовать указателю цвета пикселя рисунка. Назовите ее SBColor. Установите у этой кнопки, как и у предыдущей, свойство Grouplndex равным 1 (это обеспечит, что только одна из кнопок SBBrush или SBColor может быть нажата) и свойство AllowAllUp в true. Желательно загрузить в свойство Glyph пиктограмму (например файл..\lmages\ Buttons\one2one.bmp). 7. Перенесите на форму диалог OpenPictureDialog. 8. Перенесите на форму главное меню MainMenu. В меню задайте раздел Файл с подразделом Открыть. Назовите этот подраздел МОреп. Задайте еще один раздел — Правка с подразделом Отменить. Назовите этот подраздел Undo.
Теперь размещение компонентов закончено и можно писать обработчики событий. Начнем со второстепенных обработчиков. 9. В раздел implementation включите объявление переменной var BitMap:TBitMap; Эта переменная будет тем объектом, в котором будет сохраняться изображение, чтобы его можно было восстановить командой Отменить. 10. Для события OnCreate формы напишите обработчик вида: procedure TForml.FormCreate(Sender: TObject); var HW, i: integer; begin BitMap:=TBitMap.Create; //задание свойств кисти основного и вспомогательного цветов Imagel.Canvas.Brush.Color:= clBlack; Image2.Canvas.Brush.Color:= clwhite; // заполнение окон основного и вспомогательного цветов with Imagel.Canvas do FillRect(Rect(0,0,Width,Height)); with Image2.Canvas do FillRect(Rect(0,0,Width, Height)); // задание ширины элемента палитры цветов HW:=Image4.Width div 10; // закраска элементов палитры цветов with Image4.Canvas do for i:=l to 10 do begin case i of 1: Brush.Color:= clBlack; 2: Brush.Color:= с1Aqua; 3: Brush.Color:= clBlue; 4: Brush.Color:= clFuchsia; 5: Brush.Color:= clGreen; 6: Brush.Color:= clLime; 7: Brush.Color:= clMaroon; 8: Brush.Color:= clRed; 9: Brush.Color:= clYellow; 10: Brush.Color:= clWhite; end; Rectangle((i-1)*HW, 0, i*HW, Height); end; - // рисование креста на холсте - только для тестирования with Image3 do begin Canvas.MoveTo(0,0); Canvas.LineTo(Width,Height);, Canvas.MoveTo(0,Height); Canvas.LineTo(Width,0); end; BitMap.Assign(Image3.Picture); end; Обработчик длинный, но смысл его достаточно прост.
11. В обработчик события формы OnDestroy запишите оператор BitMap.Free; который освобождает память при закрытии приложения. 12. Для подраздела меню Открыть в обработчик включите операторы: if OpenPictureDialogl.Execute then begin ImageS.Picture.LoadFromFile(OpenPictureDialogl.File Name); BitMap.Assign(ImageS.Picture); end; Эти операторы загружают в компонент ImageS файл изображения, который пользователь выбирает в диалоге, и запоминают изображение в BitMap. 13. Для подраздела меню Отменить в обработчик включите оператор: Image3.Picture.Assign(BitMap); Этот оператор восстанавливает на холсте изображение, сохраненное в BitMap. 14. В обработчик события OnClick кнопок SBBrush и SBColor запишите оператор if (Sender as TSpeedButton).Down then BitMap.Assign(Image3.Picture); Этот оператор запоминает текущий вид изображения перед началом работы с очередным инструментом. 15. В обработчик события OnMouseDown компонентов Image3 и Image4 вставьте код:
if (Sender = Image4) or SBColor.Down then // режим установки основного и вспомогательного цветов begin if(Button=mbLeft) then with Imagel.Canvas do begin // установка основного цвета Brush.Color:=(Sender as TImage).Canvas.Pixels[X,Y]; FillRect(Rect(0,0,Width,Height)); end else with Image2.Canvas do begin //установка вспомогательного цвета Brush.Color:= (Sender as TImage).Canvas.Pixels[X,Y]; FillRect(Rect(0,0,Width,Height)); end; end else if SBBrush.Down then with Image3.Canvas do begin // режим закраски указанной области холста if Button = mbLeft then Brush.Color:= Imagel.Canvas.Brush.Color else Brush.Color:= Image2.Canvas.-Brush.Color; FloodFill(X, Y, Pixels[X,Y], fsSurface); end; Это основной код, осуществляющий как установку основного и вспомогательного цветов, так и функцию инструмента графического редактора — кисти. Если кнопка мыши нажата на палитре цветов Image4 или если кнопка SBColor — кнопка указателя цвета утоплена, то приложение находится в режиме установки цветов. При нажатой левой кнопки мыши цвет пикселя под курсором мыши передается в окно основного цвета, а при нажатии правой кнопки— в окно вспомогательного цвета. Если кнопка мыши нажата на холсте Image3 и при этом кнопка SBBrush утоплена, то приложение находится в режиме закраски указанной области рисунка. В этом случае в зависимости от нажатой кнопки мыши выбирается основной или вспомогательный цвет и функцией FloodFill производится закраска области, координаты внутренней точки которой указаны курсором мыши, а цвет — цветом пикселя, на который указывает мышь.
Если вы выполните команду Правка | Отменить, то изображение вернется к тому виду, какой был при начале работы с последним использованным инструментом. Теперь вы можете загрузить командой Файл | Открыть вашего приложения какое-то изображение. Вы можете попробовать перекрашивать те или иные области изображения. Например, можете изменить цвет фона, выделить какую-то сплошную область рисунка одного цвета и т.п. Итак, вы реализовали два из основных "инструментов любого графического редактора рисунков: кисть и индикатор цвета. Реализация остальных типичных инструментов требует предварительного ознакомления с режимами рисования, что будет сделано в следующем разделе. После этого вы сможете при желании вернуться к вашему графическому редактору и попробовать реализовать, например, инструменты, рисующие различные фигуры и перемещающие фрагменты изображения. Режимы рисования
У пера Реn имеется еще одно свойство, которое мы пока не рассматривали. Это | свойство — Mode (режим). По умолчанию значение Mode = pmCopy. Это означает, что линии проводятся цветом, заданным в свойстве Color. Но возможны и другие режимы, в которых учитывается не только цвет Color, но и цвет соответствующих пикселей фона. Наиболее интересным из этих режимов является режим pmNotХоr — сложение с фоном по инверсному исключающему ИЛИ. Операция инверсного исключающего ИЛИ анализирует по битам два своих операнда. Результирующий бит равен «0», если соответствующие биты двух операндов не равны друг другу, а при равенстве битов операндов результирующий бит равен «1».
Вспомните, что каждый пиксель хранит цвет как набор битов. Пусть, например, фоновый пиксель имеет значение 0110011, а цвет пера установлен в 1111000, Применение операции pmNotXor к этим двум числам даст цвет со значением 0110100. Этот цвет перо задаст данному пикселю. А теперь посмотрим, что получится, если перо повторно пройдет по тому же пикселю. В этом случае опять будет выполнена операция pmNotXor по отношению к цвету пера 1111000 и текущему цвету пикселя, который стал равен 0110100. Применение pmNotXor к этим числам даст в результате 0110011, т.е. первоначальный цвет пикселя. Это значит, что если нарисовать на фоне какую-то фигуру один раз, а затем нарисовать ту же фигуру повторно, то нарисованная фигура исчезнет и каждый пиксель вернется к своему первоначальному цвету. Эту особенность режима pmNotXor, свойственную также режиму pmХоr — сложение с фоном по исключающему ИЛИ, можно использовать для создания простенькой анимации. Достаточно нарисовать нечто, затем стереть нарисованное, перерисовать немного измененным - и рисунок будет представляться ожившим. Ранее мы рассматривали и использовали копирование одного графического объекта в другой методом Assign. Однако у канвы имеются и другие методы копирования. Это, прежде всего, метод CopyRect, позволяющий копировать прямоугольную область источника изображения в прямоугольную область данной канвы. Метод определен следующим образом: procedure CopyRect(Dest: TRect; Canvas: TCanvas; Source: TRect); Параметр Dest определяет прямоугольную область канвы, в которую производится копирование. Параметр Canvas указывает источник, из которого копируется изображение. Это может быть канва любого компонента: типа TImage, типа TBitMap и др. В частном случае источником может быть и канва того же компонента, в который производится копирование. Параметр Source определяет прямоугольную область в источнике изображения, которая копируется в область Dest. Копирование — это не просто перенос изображения. В общем случае копирование означает сложное взаимодействие копируемого изображения и того, которое было до этого в области, куда производится копирование. Характер этого взаимодействия определяется параметром CopyMode (режим копирования) той канвы, в которую производится копирование. По умолчанию значение CopyMode равно cmSrcCopy. Это единственный режим, при котором производится действительное копирование: изображение в Dest стирается и заменяется скопированным. Есть два значения — cm Whiteness и cmBlackness, при которых собственно никакое копирование не производится: просто область закрашивается соответственно белым или черным цветом. А все остальные режимы определяют сложное взаимодействие копируемого изображения с тем, которое было в Dest. Особый интерес представляет режим cmSrdnvert, при котором изображения канвы и источника комбинируются, используя булеву операцию XOR. Так же, как мы видели это для пера, повторное копирование в подобном режиме восстанавливает прежнее изображение на канве. Приведем примеры копирования в различных режимах. Операторы ImageI.Canvas.CopyMode:= cmSrcCopy; Imagel.Canvas.CopyRect(Rect(0,0,200,200),Image2.Canvas; Rect(0,0,200,:200)); обеспечивают копирование изображения фрагмента канвы компонента Image2 в указанную область канвы компонента Imagel. Изображение, которое ранее было на канве компонента Imagel в пределах области с координатами углов (0, 0) и (200, 200), просто заменяется новым. Операторы Imagel.Canvas.CopyMode:= cmSrdnvert; Imagel.Canvas.CopyRect(Rect(0,0,200,200),Image2.Canvas, Rect(0,0,200,200)); Imagel.Canvas.CopyRect(Rect(0,0,200,200),Image2.Canvas, Rect(0,0,200,200)); обеспечивают копирование изображения фрагмента канвы компонента Image2 в указанную область канвы компонента Imagel в режиме cmSrdnvert. После выполнения функции CopyRect в первый раз изображения в компонентах Imagel и Image2 налагаются друг на друга, а в результате выполнения функции CopyRect во второй раз исходное изображение на канве компонента Imagel восстанавливается. Операторы Imagel.Canvas.CopyMode:= cmWhiteness; Imagel.Canvas.CopyRect(Rect(0,0,200,200),Image2.Canvas, Rect (0,0,200,200)); просто очищают указанную область канвы компонента Imagel, закрашивая ее белым цветом. При этом изображение в компоненте Image2 никак не участвует в операциях копирования. Попробуйте сделать приложение, которое позволяет посмотреть большинство режимов копирования. Помимо копирования свойство CopyMode используется также методом рисования на канве Draw. Его описание: procedure Draw(X, Y: Integer; Graphic: TGraphic); Метод Draw рисует изображение, содержащееся в объекте, указанном параметром Graphic, сохраняя исходный размер изображения в его источнике и перенося изображение в область канвы объекта, верхний левый угол которой определяется параметрами X и Y. Источник изображения может быть битовой матрицей, пиктограммой или метафайлом. Если источник — объект типа TBitmap, то перенос изображения производится в режиме, установленном свойством канвы СоруMode. Например, оператор ImageI.Canvas.Draw(10,10,Bitmapl); рисует на канве компонента Imagel изображение из компонента Bitmap1 в область с координатами левого верхнего угла (10, 10). Еще один метод рисования — DrawFocusRect. Этот метод рисует изображение прямоугольника в виде, используемом для отображения рамки фокуса, операцией XOR. Функция DrawFocusRect объявлена следующим образом: procedure DrawFocusRect(const Rect: TRect); где Rect — прямоугольная область. Поскольку при рисовании используется операция XOR, то повторный вызов этого метода с тем же значением Rect удаляет изображение прямоугольника.
|
|||||||||||||||||
Последнее изменение этой страницы: 2016-12-28; просмотров: 276; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.144.117.19 (0.01 с.) |