15.11. Rad sa grafikom
Klasa Graphics
Za crtanje u C# aplikacijama možemo da koristimo površinu neke sistemske kontrole. To postižemo korišćenjem metoda ugrađene klase Graphics. Objekat klase Graphics predstavlja površinu po kojoj crtamo. Prvo ga moramo kreirati, a zatim koristiti. Pozivanjem metode CreateGraphics() za neku kontrolu, kreira se objekat klase Graphics tako da je površina za crtanje upravo ta kontrola.
Klasa Graphics sadrži metode za crtanje raznih oblika, između ostalog:
- DrawLine – za crtanje linija;
- DrawEcllipse – za crtanje elipse;
- DrawRectangle – za crtanje pravougaonika;
- DrawArc – za crtanje proizvoljnog luka;
- DrawBezier – za crtanje krive linije oko četiri tačke;
- FillEllipse – za crtanje popunjene elipse;
- FillRectangle – za crtanje popunjenog pravougaonika.
npr: g.Clear(Color.White); // briše i popunjava kontrolu belom bojom
Pri kreiranju metoda za crtanje, neophodno je kreirati olovku (objekat klase Pen) ili četku (objekat klase SolidBrush).
Klasa Pen
Objektom klase Pen definišemo boju, širinu i stil linija i krivih koje crtamo. Svojstva:
- Color – struktura tipa Color;
- Width – širina linije tipa float;
- DashStyle – može biti Dash, DashDot, DashDotDot, Dot (u imenskom prostoru System.Drawing.Drawing2D);
npr: Pen olovka=new Pen(Color.Red,5);
Klasa SolidBrush
Pri crtanju popunjenih oblik (pravougaonik, elipsa) koristimo objekte klase SolidBrush.
Svojstva:
- Color – struktura tipa Color;
Kreirani objekti klase Graphics, Pen i Brush zauzimaju odgovarajuće rasurse našeg sistema pa je potrebno, po završetku crtanja, osloboditi resurse korišćenjem metode Dispose() klase Graphics.
Možemo koristiti događaj Paint za kontrolu, a on se pokreće po učitavanju kontrole, ali i svaki put kada se kontrola iscrtava (postaje ponovo vidljiva ili osveži prikaz). Možemo je pozvati i eksplicitno u bilo kom delu aplikacije, pozivom metode Refresh().
npr: DrawLine(Pen olovka,Point A, Point B); ili DrawLine(Pen olovka,intx1,int y1,int x2, int y2);
Klasa Color
Boja je određena strukturom Color. Ova struktura sadrži static atribute (nepromenljive tj. iste za sve podklase) kojima su predstavljene najčešće korišćene boje (Red, Green, Blue, Yellow, Black, White...) ali i metod kojim možemo da definišemo boju:
Vrednosti nivoCrvene, nivoZelene i nivoPlave su celi brojevi od 0 do 255.
Klasa Random
Klasu Random koristimo za generisanje slučajnih brojeva. Prvo kreiramo objekat te klase pozivom konstruktora klase:
Metod kojim generišemo slučajne brojeve je Next i on ima tri varijante:
- Next() vraća nenegativan slučajan 32-bitni ceo broj;
- Next(maxVrednost) vraća nenegativan slučajan 32-bitni ceo broj manji od maxVrednost;
- Next(minVrednost, maxVrednost) vraća nenegativan slučajan 32-bitni ceo broj veći ili jednak minVrednost i manji od maxVrednost;
1. zadatak
Napraviti aplikaciju u kojoj treba da se klikom na formu prouzrokuje slučajna promena boje pozadine forme, a u naslovnoj liniji treba da se ispiše informacija o koordinatama tačke na koju je kliknuto.
private void Form1_Load(object sender, EventArgs e)
{
Text = "Klikni na formu";
Width = 500;
Height = 500;
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
Random R = new Random();
BackColor = Color.FromArgb(R.Next(256),R.Next(256),R.Next(256));
Text = "Kliknuli ste na polje ("+e.X+","+e.Y+")";
}
Dijalog za izbor boje: ColorDialog
ColorDialog je dijalog koji nudi opciju biranja boja. Kada korisnik odabere određenu boju, to se prosleđuje aplikaciji prilikom zatvaranja dijaloga. Pozivanje ovog dijaloga vrši se pomoću metode ShowDialog().
ColorDialog dlg = new ColorDialog();
dlg.ShowDialog();
Metoda ShowDialog() kao rezultat vraća akciju korisnika u dijalogu. Ova akcija predstavlja enumeraciju pod nazivom DialogResult. Nama su zasad od interesa samo dve opcije:
DialogResult.OK - korisnik je kliknuo na OK
DialogResult.Cancel - korisnik je kliknuo na Cancel
Od svojstava, zasad nas interesuje samo
Color - odabrana boja
2. zadatak
Klikom na dugme treba da se otvori dijalog za izbor boje. Izabrana boja treba da se ispiše u MessageBox-u.
private void button1_Click(object sender, EventArgs e)
{
ColorDialog dlg = new ColorDialog();
if (dlg.ShowDialog() == DialogResult.OK)
{
string str = null;
str = dlg.Color.Name;
MessageBox.Show(str);
}
}
Pomoću metode dlg.ShowDialog() otvaramo dijalog i odmah proveravamo njegovu povratnu vrednost. Ako je ona jednaka DialogResult.OK, to znači da je korisnik odabrao boju i kliknuo na dugme "OK" u dijalogu.
U tom slučaju se u svojstvu Color nalazi koja je boja izabrana. Nazivu boje se pristupa ca dlg.Color.Name, naravno ako ta boja ima naziv, a ako nema onda će to biti rgb kod za datu boju. U prozoru za prikaz poruke
se ispisuje naziv boje.
podzadatak: izabrana boja treba da se postavi na pozadinu forme.
- ovo se radi na času, samostalno (od strane učenika)
Tačka:
Pod tačkom podrazumevamo objekat klase Point ili PointF. Prvi se zadaje celobrojnim, a drugi realnim koordinatama. Konstruktoru najčešće prosleđujemo samo dva broja, koordinate tačke koju definišemo, kao na primer:
Point p1 = new Point(10, 20);
PointF p2 = new PointF(10.2, 20.4);
Crtanje linije
Za crtanje linije se koristi nekoliko funkcija sa zajedničkim imenom DrawLine, koje su takođe metode klase Graphics.
• DrawLine(Pen p, PointF a, PointF b)
• DrawLine(Pen p, Point a, Point b)
• DrawLine(Pen p, Int32 x1, Int32 y1, Int32 x2, Int32 y2)
• DrawLine(Pen p, float x1, float y1, float x2, float y2)
Kao i kod drugih Draw… metoda, prvi parametar je olovka (Pen), pomoću koje zadajemo boju i debljinu
linije. Naredni parametri na različite načine zadaju krajeve duži. Krajevi duži se mogu zadati kao dve tačke (objekti tipa Point ili PointF) ili pomoću dva para koordinata (ukupno 4 broja), a koordinate mogu biti celobrojne ili realne
(
float) i predstavljaju vrednosti u pikselima. Tako na primer, pomoću sledećih naredbi
Graphics g = e.Graphics;
Pen olovka = new Pen(Color.Blue, 2);
g.DrawLine(olovka, 20, 10, 40, 30);
iscrtava se plava linija debljine 2 piksela od tačke (20,10) do tačke (40,30).
Zadatak br 3. Crtanje Linije
Kreirajmo novu formu koju ćemo nazvati Grafika na kojoj ćemo da nacrtamo jednu pravu liniju plave boje koja će biti usmerena od gornjeg
levog ugla ka donjem desnom uglu forme.
private void Grafika_Paint(object sender, PaintEventArgs e)
{
Graphics graf = e.Graphics;
Pen olovka = new Pen(Color.Blue, 15);
int sirina = ClientRectangle.Width;
int visina = ClientRectangle.Height;
Point pocetakLinije, krajLinije;
pocetakLinije = new Point(sirina / 4, visina / 4);
krajLinije = new Point(3 * sirina / 4, 3 * visina / 4);
graf.DrawLine(olovka, pocetakLinije, krajLinije);
olovka.Dispose();
}
Kao rezultat izvršenja programa (izbor stavke Linija u meniju Grafika u glavnoj formi) dobija se plava linija
Analizirajmo kod koji se izvršava za događaj Paint. Najpre je kreiran objekat klase Graphics. Zatim je kreiran objekat klase Pen koja
definiše kako će izgledati linija kojom se crta (grubo rečeno kakvom olovkom ćemo crtati) tj. oblik linije, debljina linije, boja, itd.
Olovku smo podesili na plavu
boju i debljinu linije od 15 pointa tako što su Color.Blue i 15 korišćeni kao argumenti konstruktora klase Pen. Linija koja se
iscrtava primenom metode DrawLine spaja dve prethodno definisane tačke: pocetakLinije i krajLinije koje predstavljaju objekte klase Point. Ova klasa
ima konstruktor čiji su argumenti celobrojne koordinatne X i Y izražene kao broj pixela. Interesantno je kako su određene ove dve
tačke.
Šta će se desiti ako promenimo veličinu prozora tj. forme Grafika (klik miša na donji desni ugao forme u oblasti 6 sivih tačkica u obliku trougla i pomeranje miša)? Primetićemo
da se i linija menja u skladu sa promenom veličine forme. Kako je to postignuto? Primetićete da su za određivanje krajnjih tačaka
linije korišćene dve pomoćne promenljive sirina i visina koje su postavljene na širinu odnosno visinu oblasti forme na po kojoj može da se
crta (tj. koja je pod kontrolom korisnika) a predstavljena je osobinom ClientRectangle koja ima osobine Width i Height. Tačke smo odredili relativno u odnosu na ClientRectangle tj. kao jedna odnosno
tri četvrtine širine
odnosno visine. Na ovaj način će se svaki put kada promenimo veličinu forme Grafika promeniti i apsolutni položaji tačaka koji će relativno u odnosu na veličinu forme biti na istom mestu.
Napomena: Na osnovu prethodnog može se zaključiti
da će se metoda za crtanje Grafika_Paint() tj. u opštem slučaju događaj Paint pozivati od strane sistema svaki put kada se nešto desi sa formom (u našem slučaju to
je promena veličine forme).
Na kraju se pozivom metode Dispose() oslobađaju resursi zauzeti pri kreiranju objekta olovka klase Pen.
4. zadatak
Kreirati aplikaciju kojom se crtaju linije kojima je koordinata početne tačke određena položajem strelice miša u trenutku pritiska dugmeta miša, a koordinata krajnje tačke određena položajem strelice miša u trenutku otpuštanja dugmeta
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int xt, yt;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
xt = e.X;
yt = e.Y;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
Graphics g = CreateGraphics();
Pen olovka=new Pen(Color.Black);
g.DrawLine(olovka, xt, yt, e.X, e.Y);
g.Dispose();
olovka.Dispose();
}
}
Podzadatak 1: U ovoj aplikaciji uraditi iscrtavanje linija tako da svaka sledeća linija ima slučajno izabranu boju
Podzadatak 2: Umesto slučajnog izbora boje ubaciti dugme za izbor boje, tako da se svaka sledeća linija iscrtava u boji koju odabere korisnik
Dopunski materijali, za bolje razumevanje pogledajte sledeći materijal, za koji je postavljen link za preuzimanje: Osnove programskog jezika C#.NET
- Za one kojima je potrebno, ponavljanje:
-
- Kako se pravi projekat (ako ne znate, pročitajte sa strana 47-52 )
- Šta je programiranje vođeno događajima (na stranama 52-53 )
- Kako se dodaje nova forma i u čemu je razlika između modalne i nemodalne forme ( na stranama 53-55 )
- kako se stavljaju meniji (ako dosad niste naučili, nalazi se od strane 71 pa nadalje)