Графіка в delphi
Робота з графікою в Delphi це не тільки лінії і малюнки, але також і та друк текстових документів. Тому в Delphi роботі з графікою потрібно приділити трохи часу. Робота з графікою в Delphi передбачає звернення до канві - властивості Canvas компонентів. Canvas Delphi це полотно, який дозволяє програмісту мати доступ до кожної своєї точки (пікселя), і немов художнику відображати те, що потрібно. Звичайно, малювати попиксельно для роботи з графікою в Delphi не доводиться, система Delphi надає для потужні засоби роботи з графікою. полегшують завдання програміста.
Звичайно, не всі компоненти в Delphi мають ці властивості. На вкладці Additional розташований спеціалізований компонент TImage. спеціально призначений для малювання, але також властивість Canvas мають, наприклад, такі компоненти як ListBox, ComboBox, StringGrid, а також і сама Форма, яка розміщує наші компоненти! Крім того, для друку документів Delphi звертається до властивості Canvas такого об'єкта як принтер.
Основна властивість такого об'єкта як Canvas Delphi - Pixels [i, j] типу TColor. тобто це двовимірний масив точок (пікселів), що задаються своїм кольором. Малювання на канві відбувається в момент присвоєння будь-якій точці канви заданого кольору. Кожному пікселю може бути присвоєно будь-який доступний для Windows колір. Наприклад, виконання оператора
приведе до малювання червоною точки з координатами [100, 100]. Дізнатися колір пікселя можна зворотним присвоєнням:
Тип TColor визначений як довге ціле (LongInt). Його чотири байти містять інформацію про частки синього (B), зеленого (G), і червоного (R) квітів. У 16-річної системі це виглядає так: $ 00BBGGRR. Частка кожного кольору може змінюватися від 0 до 255. Тому щоб відобразити максимально червону крапку, їй потрібно привласнити колір $ 000000FF.
Для стандартних кольорів в Delphi визначений набір текстових констант. Побачити його можна, відкривши в інспектор об'єктів властивість Color, наприклад, тієї ж форми.
Наступна таблиця містить деякі властивості і методи канви:
Процедура TextOut (X, Y: Integer; const Text: WideString);
Виробляє виведення рядка Text починаючи з (X, Y) - лівого верхнього пікселя тексту.
Властивість TextWidth (var Text: String): Integer;
Містить довжину рядка Text в пікселах.
Властивість TextHeight (var Text: String): Integer;
Містить висоту рядка Text в пікселах.
Процедура FillRect (const Rect: TRect);
Заповнює прямокутник Rect на полотні, використовуючи поточну кисть. Може використовуватися, в тому числі, для стирання частини зображення на полотні.
Напишемо, використовуючи тільки ці методи канви, додаток для зображення на канві компонента Image тексту, який вводиться в компонент Memo:
Розмістіть на формі компоненти Memo, Image (знаходиться на сторінці Additional), Edit, UpDown (знаходиться на сторінці Win32). Властивість Associate компонента UpDown прирівняти в випадаючому списку нашому компоненту Edit. Цим компонентом ми будемо змінювати розмір шрифту. Оскільки і Memo і Image знаходяться у нас на одному пристрої виведення - на нашому екрані, розмір пікселя у них однаковий, і тому розміри зображення будуть рівні.

Перше, що ми зробимо, це ініціалізацію змінних при старті програми. Необхідно визначити розміри області малювання (створимо для цього глобальну змінну Rect типу TRect) і зробити колір фону Image білим:
procedure TForm1.FormCreate (Sender: TObject);
begin
Rect.Left: = 0;
Rect.Top:=0;
Rect.Right: = Image1.Width;
Rect.Bottom: = Image1.Height;
Image1.Canvas.Brush.Color: = clWhite;
end;
Потім намалюємо рамку по сторонам Image:
procedure TForm1.page;
begin
with Image1.Canvas do
begin
MoveTo (0, 0);
LineTo (Image1.Width-1, 0);
LineTo (Image1.Width-1, Image1.Height-1);
LineTo (0, Image1.Height-1);
LineTo (0, 0);
end;
end;
Спробуємо, що вийшло. Все працює, але рамка поки не виводиться. Тому додамо процедуру page в в процедуру FormCreate. Тепер красиво. Далі напишемо просту процедуру стирання, очищення Image. Її потрібно буде викликати перед будь-яким оновленням зображення, інакше попереднє і наступне зображення будуть перекриватися.
procedure TForm1.clearing;
begin
Image1.Canvas.FillRect (Rect); // Прямокутник Rect заповнюється білим кольором, зображення стирається.
end;
Тепер прийшла черга безпосередньо процедури виведення тексту. Почнемо виводити текст від точки (3, 3) - верхнього лівого кута листа, з невеликим відступом в 3 пікселя. Кожну наступну рядок будемо зміщувати на висоту рядка:
procedure TForm1.prn;
var i: Integer;
begin
with Image1.Canvas do
for i: = 1 to Memo1.Lines.Count do
TextOut (3, 3 + (i-1) * TextHeight ( 'A'), Memo1.Lines [i-1]);
end;
Тепер все готово для перегляду тексту. Робити це будемо за подією OnChange:
procedure TForm1.Memo1Change (Sender: TObject);
begin
clearing;
prn;
page;
end;
Ну і наостанок процедура зміни розміру шрифту:
procedure TForm1.Edit1Change (Sender: TObject);
begin
Memo1.Font.Size: = UpDown1.Position;
Image1.Canvas.Font.Size: = UpDown1.Position;
Memo1Change (Sender);
end;
Можна модифікувати цю програму для виведення тексту на друк. Для роботи з принтером потрібно підключити модуль Printers:
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Printers;
При роботі з принтером як з полотном, щоб розпочати друк викликається метод BeginDoc. потім проводиться висновок документа, завершується друк викликом методу EndDoc:
Printer.BeginDoc;
with Printer.Canvas do
begin
. Друк документа.
end;
Printer.EndDoc;
Ширина і висота полотна принтера доступні через властивості Printer.PageWidth і Printer.PageHeight. Закінчити друк на одній сторінці і почати друкувати на інший можна за допомогою методу Printer.NewPage.
Він приймає параметри
Rect - прямокутник з розмірами малюнка
var Rect: TRect;
Graphic - один з класів зображень, наприклад TBitmap
var Foto: TBitmap;
Відповідно, в обробнику OnCreate Форми створюємо прямокутник з розмірами Форми:
Rect.Left: = 0;
Rect.Top:=0;
Rect.Right: = Width;
Rect.Bottom: = Height;
і об'єкт Bitmap:
Bitmap має метод завантаження зображень:
Виводити малюнок потрібно не в момент створення Форми, а з невеликою затримкою, я ввів її за допомогою таймера, що має затримку 10 мс. От і все. вийшло:
var
Form1: TForm1;
Rect: TRect;
Foto: TBitmap;
Application.Icon.LoadFromFile ( 'ім'я файлу з іконкою');
наступні рядки слідом за procedure FormCreate (Sender: TObject);
ось зумів зробити синусоїду, але без періоду, ось код - працює!
Я б простіше робив. Спочатку провів би координатну лінію по осі Х: і зарубки, відповідні періоду в 2 * Pi:
Canvas.MoveTo (0, Height div 2);
Canvas.LineTo (Width, Height div 2);
PX: = 0;
Period: = 2 * Pi;
Yo: = Trunc (Height / 2);
while PX
Потім будував би графік функції Y: = sin (X) + sin (X / 5):
Canvas.MoveTo (0, Height div 2);
for PX: = 0 to Width do
begin
Y: = sin (Px) + sin (Px / 5);
Py: = Yo-trunc (Y);
Canvas.LineTo (Px, Py);
end;
Але виходить не графік, а мазня - все занадто дрібно. Вводимо масштаб, по Х в 20 разів, а по Y в усі 100. І ось що виходить:
procedure TForm1.FormPaint (Sender: TObject);
var X, Y: Real;
Period: Real;
Mx, My, Px, Py, Yo: Integer;
begin
Mx: = 20; My: = 100;
Canvas.MoveTo (0, Height div 2);
Canvas.LineTo (Width, Height div 2);
Canvas.MoveTo (0, Height div 2);
Period: = 2 * Pi * Mx;
Yo: = Trunc (Height / 2);
for Px: = 0 to Width do
begin
Y: = sin (Px / Mx) + sin (Px / 5 / Mx);
Py: = Yo-trunc (Y * My);
Canvas.LineTo (Px, Py);
end;
X: = 0;
Canvas.Pen.Width: = 2;
Canvas.Pen.Color: = clRed;
while X
Єдино, зарубки переніс вниз процедури, пофарбував у червоний колір, і зробив товстіший. кирило, додано 28.02.12, 17:40:03
Добрий вечір, не можу доробити роботу підкажіть: необхідно щоб окружність малого радіуса рухалася по лініях семілучевие зірки. ось напрацювання мої:
procedure TForm3.a (Sender: TObject; var Key: Char);
begin
cc: = key; edit1.Text: = key;
end; // відповідає за управління процесом
procedure TForm3.s (Sender: TObject);
var x, y, r, j, i: word; B: array [1..360] of integer; G: array [1..360] of integer;
a: real;
begin
R: = 200;
for i: = 0 to 360 do
begin
if i mod 45 = 0 then
a: = (i * pi) / 180;
x: = 250 + round (R * cos (a));
y: = 250 + round (R * sin (a));
b [i]: = x; g [i]: = y;
end;
canvas.MoveTo (b [45], g [45]);
canvas.LineTo (b [180], g [180]);
canvas.LineTo (b [315], g [315]);
canvas.LineTo (b [90], g [90]);
canvas.LineTo (b [225], g [225]);
canvas.lineto (b [360], g [360]);
canvas.LineTo (b [135], g [135]);
canvas.LineTo (b [270], g [270]);
canvas.LineTo (b [45], g [45]); // накреслив семикутник.
begin
form3.Color: = clnavy;
form3.KeyPreview: = true;
canvas.Pen.Width: = 3; a: = 0;
repeat
Application.processMessages;
canvas.Pen.Color: = clyellow;
canvas.ellipse (x, y, x + 12, y + 12);
sleep (5);
canvas.Pen.color: = clNavy;
Canvas.Ellipse (x, y, x + 12, y + 12); // пустив еліпс з однаковими радіусами по лініях. але ось це і не виходить.
until cc = 'q'; // клавіша q відповідає за кінець операції інакше не зупинити.
Далі. Малюємо еліпс.
canvas.Pen.Width: = 3; a: = 0;
repeat
Application.processMessages;
canvas.Pen.Color: = clyellow;
canvas.ellipse (x, y, x + 12, y + 12);
sleep (5);
canvas.Pen.color: = clNavy;
Canvas.Ellipse (x, y, x + 12, y + 12);
until cc = 'q';
a: = 0; - навіщо, де це використовується?
Як буде рух здійснюватися? Координати ж не змінюються.
А як ви збираєтеся обчислювати кожен піксель вашої зірки, щоб еліпс по ній йшов? Це не констатація помилки, просто цікаво.
І гарніше коли центр кола рухається по лінії, а у вас кут квадрата, куди вона вписана. Правильніше так:
А зупинка руху. Через введення символу в Edit. Природніше ввести змінну
var Move: Boolean = False;
repeat
обчислення
until Move = False;
Ну і міняти змінну натисканням кнопки:
Form1.Canvas.Ellipse (100, 100, 200, 200);
І все нарісуется.Напішіте ваш варіант, разом подивимося що не так.
procedure TForm1.Button1Click (Sender: TObject);
var x1, y1, x2, y2: Integer;
begin
X1: = 100; y1: = 100;
X2: = 200; y2: = 200;
canvas.Ellipse (x1, y1, x2, y2);
end;
Read (F, x, y, radon);
case radon of
1..10: Image1.Canvas.Brush.Color: = clGreen;
11..20: Image1.Canvas.Brush.Color: = clYellow;
21..30: Image1.Canvas.Brush.Color: = clRed;
Image1.Canvas.Ellipse (x-6, y-6, x + 6, y + 6);
end;
Image1.Canvas.Ellipse (x-6, y-6, x + 6, y + 6);
procedure TForm1.Timer1Timer (Sender: TObject);
begin
Image1.Canvas.MoveTo (Xo, Yo);
Image1.Canvas.LineTo (X1, Y1);
Xo: = X1;
Yo: = Y1;
end;
procedure TForm1.Image1MouseDown (Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Timer1.Enabled = False then
begin
Xo: = X;
Yo: = Y;
Timer1.Enabled: = True;
end;
end;
procedure TForm1.Image1MouseUp (Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Timer1.Enabled: = False;
end;
Іноді виникає ситуація, коли необхідно в ході виконання програми змінити розміри компонента TImage, а потім на його полотні щось намалювати. Але все нові малюнки на полотні TImage обмежені старими габаритами. Як це вирішити?
Необхідно разом з розмірами TImage змінити розміри його Bitmap.
Image1.Height: = 80;
Image1.Width: = 33;
Image1.Picture.Bitmap.Height: = 80;
Image1.Picture.Bitmap.Width: = 33;
RelatedCommand line calculator on Rails - dentaku
In "Програмування" Як змінити стандартний crHandPoint на системний (Delphi)
In "Програмування" Хто викликав PopupMenu? (Delphi)
In "Програмування"