Afişarea grafică Subsistemul care tratează afişarea grafică se numeşte GDI+. GDI (Graphical Device Interface) a fost modelul grafic din Windows începând cu Windows 3.0. De-a lungul timpului acesta a fost mult îmbunătăţit pentru cadrul de lucru C++ (.NET Framework), astfel explicându-se adăugarea semnului (+). GDI+ oferă o bibliotecă de clase pentru efectuarea de operaţii grafice. Funcţionalitatea interfeţei GDI+ se întinde peste mai multe spaţii de nume. o System::Drawing asigură funcţionalitatea de bază; o System::Drawing::Drawing2D pune la dispoziţie funcţii grafice bidimensionale şi vectoriale mai avansate; o System::Drawing::Imaging asigură funcţionalitatea pentru prelucrarea de imagini; o System::Drawing::Text oferă funcţii tipografice suplimentare faţă de System::Drawing o System::Drawing::Printing tratează operaţiile de tipărire. Spaţiile de nume System::Drawing Principalele clase din System::Drawing sunt: Clasa Bitmap Brush Brushes Color Font FontFamily Graphics Icon Image Pen Pens Point, PointF Rectangle, RectangleF Region Descrierea Reprezintă un obiect bitmap. Această clasă poate lucra cu câteva formate standard, printre care : BMP, GIF, şi JPG. Clasă care reprezintă pensule pentru umplerea interioarelor diverselor forme. O colecţie de pensoane. Structură care reprezintă o culoare.. Reprezintă un font. Reprezintă o familie de fonturi. Reprezintă o suprafaţă de desen. Reprezintă un obiect icon. Clasă abstractă care stă la baza altor clase, printre care Bitmap şi Metafile. Clasă ale cărei obiecte reprezintă creioanele folosite pentru desenarea formelor şi contururilor. O colecţie de pensoane. Clase folosite pentru reprezentarea punctelor ce au coordonatele X,Y întregi sau în virgulă mobilă. Clase folosite pentru reprezentarea dreptunghiurilor (valori întregi sau în virgulă mobilă). Reprezintă o regiune (nu neapărat dreptunghiulară) 1
Clasa Size, SizeF SolidBrush StringFormat TextureBrush Descrierea Structurile de tip întreg sau în virgulă mobilă care reprezintă o dimensiune. O pensulă care utilizează o culoare pentru a umple formele. Încapsulează un set de informaţii de machetare a textelor, cum ar fi: alinierea şi spaţierea liniilor. O pensulă care utilizează o imagine pentru a umple formele. Structurile Point şi PointF Reprezintă o pereche ordonată de întregi/numere în virgulă mobilă, ce definesc un punct în plan. Accesul la aceste coordonate se face prin intermediul proprietăţilor X şi Y. Point P1(25,100); PointF P2(23.7F,7.23F); Structurile Size şi SizeF Reprezintă o pereche de întregi/numere în virgulă mobilă, ce definesc de obicei lăţimea şi înălţimea unui dreptunghi. Accesul la aceste coordonate se face prin intermediul proprietăţilor Width şi Height. Size S1(25,100),S2(P1); SizeF S3(23.7F,7.23F),S4(P2); Structurile Rectangle şi RectangleF Reţin un set de patru întregi/numere în virgulă mobilă care reprezintă locaţia şi dimensiunea unui dreptunghi. Accesul la aceste valori se face prin intermediul proprietăţilor X,Y, Width, Height. Rectangle R1(0,25,100,100), R2(P1,S1); RectangleF R3(24.5,23.7,7.23,5.2),R4(P2,S3); Utilizarea culorilor Culorile sunt reprezentate de structura System::Drawing::Color şi sunt formate din patru componente: Red, Green, Blue şi Alpha. Primele trei reprezintă cantităţile de roşu, verde şi albastru (valori cuprinse între 0 şi 255). Cantitatea Alpha reprezintă transparenţa culorii şi poate varia între 0 (complet transparent) şi 255 (complet opac). Structura Color defineşte un număr mare de proprietăţi care reprezintă culorile definite de sistem, începând cu AliceBlue şi terminând cu YellowGreen. 2
Nu există constructor definit dar se pot utiliza metodele statice FromArgb, FromKnownColor, FromName pentru a crea obiecte Color. o FromArgb crează o culoare dintr-un set de valori Alpha, Red, Green, Blue; o FromKnownColor crează un obiect Color dintr-un membru al enumerării KnownColor; o FromName crează un obiect pornind de la un nume. Exemple : Color rosu=color::fromargb(255,0,0);//o culoare opaca Color c = Color::FromArgb(110,33,66,99);//o culoare semi-transparentă Color rosu_semitransparent = Color::FromArgb(127,rosu.R, rosu.g,rosu.b); //o culoare semitransparentă Observaţie: Proprietăţile A,R,G şi B pot fi utilizate pentru a accesa componentele obiectului Color. Utilizarea fonturilor Pentru a utiliza fonturile într-un program vom folosi clasa System::Drawing::Font. Un font se poate defini specificând familia (ex. Time New Roman), dimensiunea și stilul. Printre constructorii clasei avem: public: Font(Font, FontStyle); - construiește un nou font utilizând un font existent și o enumerare FontStyle. public: Font(String, Single); - construiește un nou font pornind de la o familie de fonturi și de la o dimensiune speificată. public: Font(String, Single, FontStyle); - construiește un nou font pornind de la o familie de fonturi, de la o dimensiune speificată și de la o enumerare FontStyle. Proprietăţi specifice Nume Bold Descriere Dă o valoare care indică dacă fontul are aplicat stilul bold. FontFamily Dă valoarea FontFamily asociată fontului. Italic Name Strikeout Dă o valoare care indică dacă fontul are aplicat stilul italic. Dă numele fontului. Dă o valoare care indică dacă textul care va fi scris utilizând acest font este tăiat cu o linie orizontală. 3
Style Underline Dă informații despre stilul fontului. Dă o valoare care indică dacă fontul are aplicat stilul underline. Observație: Pentru a determina dimensiunile unui anumit text într-un context grafic se poate folosi metoda MeasureString din clasa Graphics, ca in exemplul de mai jos: Graphics ^g; SizeF ms; Font ^f;... ms=g->measurestring("text",f); ms.width;//latimea textului ms.height;//inaltimea textului Clasa Pen Obiectele clasei Pen sunt utilizate pentru a reprezenta creioanele utilizate pentru desenarea formelor şi contururilor. Obiectele Pen simple sunt create prin specificarea unei lăţimi de linie (în pixeli) şi a unei culori. Exemple: Pen^ pen1=gcnew Pen(Color::Black);//crează un creion negru cu laţimea prestabilită de un pixel Pen^ pen2=gcnew Pen(Color::Red,2.0);//crează un creion roşu cu laţimea de doi pixeli Se pot crea şi obiecte Pen mai avansate, specificând un argument Brush în loc de Color. Astfel se pot umple liniile cu imagini sau modele. Observaţie: Clasa Pens are proprietăţi care definesc peste 140 de creioane ce reprezintă gama completă de culori definite de sistem. Fiecare dintre acestea are lăţimea de un pixel. Obiecte Brush Obiectele Brush sunt de mai multe feluri, toate provenind din clasa de bază Brush. Cel mai simplu obiect este SolidBrush, care umple o suprafaţă cu o culoare omogenă. SolidBrush^ br1=gcnew SolidBrush(Color::Blue);//crează o pensulă albastră Clasa TextureBrush utilizează o imagine pentru umplerea formelor. Dacă imaginea este mai mică decât forma, poate fi multiplicată pe toată suprafaţa formei: 4
TextureBrush^ br2=gcnew TextureBrush(gcnew Bitmap("brush.bmp"), System::Drawing::Drawing2D::WrapMode::Tile); //crează un obiect TextureBrush care va fi multiplicat pe toată suprafaţa formei Observaţie: Clasa Brushes are proprietăţi care definesc pensule definite de sistem. Clasa Image Aceasta este o clasă abstractă care stă la baza claselor Bitmap şi Metafile. Proprietăţi Height HorizontalResolution Palette RawFormat Size VerticalResolution Width Dă înălţimea obiectului Image. Dă rezoluţia orizontală (pixeli-pe-inch) a obiectului Image. Dă sau setează paleta de culori utilizată de obiectul Image. Dă formatul obiectului Image: Bmp, Gif, Icon, Jpeg, Wmf etc. Dă sau setează lăţimea şi înălţimea, în pixeli, a imaginii. Dă rezoluţia verticală (pixeli-pe-inch) a obiectului Image. Dă lăţimea obiectului Image. Metode Clone FromFile FromStream GetFrameCount GetPixelFormatSize RotateFlip Save SelectActiveFrame Crează o copie a obiectului Image. Crează o imagine dintr-un fişier specificat. Overloaded. Crează o imagine dintr-un stream. Dă numărul de frame-uri ale obiectului. Dă adâncimea culorii (numărul de biţi pe pixel) pentru formatul specificat. Folosită pentru rotiri şi simetrii ale imaginii. Salvează imaginea în formatul specificat. Selectează frame-ul specificat prin dimensiune şi index. 5
Exemplu de utilizare a metodei Save: img->save("c:\\poza.bmp"); img->save("c:\\poza.bmp",imaging::imageformat::bmp); Clasa Bitmap Un obiect Bitmap reprezintă o imagine grafică (reprezentată prin pixeli) împreună cu atributele sale. Pentru crearea obiectelor Bitmap putem folosi constructorii: public: Bitmap(Image^); // crează un obiect Bitmap dintr-un obiect Image existent. public: Bitmap(Stream^); // crează un obiect Bitmap dintr-un flux dat. public: Bitmap(String^); // crează un obiect Bitmap avand la bază fişierul aflat la adresa specificată. public: Bitmap(Image^, Size); sau public: Bitmap(Image^, int, int);// crează un obiect Bitmap (de dimensiuni specificate) dintrun obiect Image existent. public: Bitmap(int, int); // crează un obiect Bitmap de dimensiuni specificate Metode specifice GetPixel MakeTransparent SetPixel SetResolution Dă culoarea pixelului specificat. Culoarea specificata devine transparenta. Setează culoarea pixelului specificat. Setează rezoluţia obiectului Bitmap. Exemplu în care încărcăm imaginea aflată la adresa "resurse\\poza.jpg" apoi afişăm alăturat imaginea iniţială şi imaginea modificată (pixelii care au iniţial culoarea egală cu cea a pixelului aflat în poziţia (2,2) devin transparenţi). Graphics ^g=p->creategraphics(); Bitmap^ bm=gcnew Bitmap("resurse\\poza.jpg"); bm=gcnew Bitmap(bm,200,200); //redimensionam g->drawimage(bm,0,0,300,250); Color c=bm->getpixel(2,2); bm->maketransparent(c); g->drawimage(bm,300,0,300,250); 6
Clasa Graphics Clasa Graphics suportă operaţii de desenare, iar un obiect al clasei Graphics reprezintă locaţia către care se trimite afişarea grafică, dar poate oferi şi informaţii despre dispozitivul utilizat. Un obiect al acestei clase reprezintă o structură de date fundamentală din Windows, denumită context de dispozitiv, fiind de fapt un intermediar între utilizator şi dispozitivul de ieşire. Obiectele clasei Graphics nu sunt create direct ci se obţin cu ajutorul metodei CreateGraphics. Graphics ^g=formularulmeu->creategraphics(); Un obiect Graphics utilizează resurse de sistem care vor fi eliberate din memorie atunci când obiectul este colectat la gunoi. Cum nu se cunoaşte momentul în care se colectează gunoiul, este recomandat ca după utilizare, resursele să fie eliberate, apelând metoda Dispose: g->dispose(); Clasa Graphics include multe metode, cele mai des utilizate fiind prezentate în tabelul de mai jos. Metode Clear Dispose DrawArc DrawBezier DrawBeziers DrawClosedCurve DrawCurve DrawEllipse DrawIcon DrawImage DrawLine DrawLines DrawPath DrawPie Umple întreaga suprafaţă de desenare cu o culoare. Eliberează resursele utilizate de obiectul Graphics. Desenează un arc de elipsă Desenează o curbă Bézier definită prin patru puncte. Desenează o curbă Bézier definită printr-un tablou de puncte. Desenează o curbă închisă definită de un tablou de puncte. Desenează o curbă având la bază un tablou de puncte. Desenează o elipsă definită de un dreptunghi delimitator. Desenează o pictogramă. Desenează imaginea specificată în locaţia precizată. Desenează o linie între două puncte precizate. Desenează o serie de segmente ce unesc punctele precizate întrun tablou de puncte. Desenează un obiect GraphicsPath. Desenează un sector de cerc definit de o elipsă şi două linii radiale. 7
DrawPolygon DrawRectangle DrawString FillClosedCurve FillEllipse FillPath FillPie FillPolygon FillRectangle FromImage MeasureString RotateTransform Save Desenează un poligon definit de un tablou de puncte. Desenează un dreptunghi. Scrie textul specificat în locaţia specificată, folosind câte un obiect Brush şi Font. Umple interiorul unei curbe închise definită de un tablou de puncte. Umple interiorul unei elipse definită de un dreptunghi delimitator. Umple interiorul unui obiect GraphicsPath. Umple interiorul unui sector de cerc definit de o elipsă şi două linii radiale. Umple interiorul unui poligon definit de un tablou de puncte. Umple interiorul unui dreptunghi. Crează un obiect Graphics nou dintr-un obiect Image. Dă dimensiunile unui text, precizîndu-se fontul folosit. Aplică o rotaţie dată de o matrice. Salvează contextul grafic reprezentat de obiectul curent. Modul de utilizare a principalelor metode este prezentat în programul următor. 8
Creăm un proiect nou numit MetodeGrafice şi pentru formularul Form1 vom stabili: ClientSize = System::Drawing::Size(738, 474); FormBorderStyle = System::Windows::Forms::FormBorderStyle::Fixed3D; MaximizeBox = false; Text = L"Exemplu de utilizare a metodelor grafice"; Adăugăm formularului un control PictureBox pentru care stabilim : BackColor = System::Drawing::Color::White; Location = System::Drawing::Point(10, 10); Name = L"p"; Size = System::Drawing::Size(720, 400); Adăugăm formularului un control Button pentru care stabilim : Location = System::Drawing::Point(323, 416); Name = L"b"; Size = System::Drawing::Size(100, 53); Text = L"Deseneaza"; Pentru evenimentul Click asociat butonului b vom avea: private: System::Void b_click(system::object^ sender, System::EventArgs^){ deseneaza(p->creategraphics()); } Unde metoda desenează este: void deseneaza(graphics^ g){ Bitmap ^bm=gcnew Bitmap("resurse\\Azul.jpg"); System::Drawing::Font ^f=gcnew System::Drawing::Font("Times New Roman",12); bm=gcnew Bitmap(bm,150,100); g->drawarc(gcnew Pen(Color::Blue,3), Rectangle(10,10,100,50),0,90);//pot fi si valori de tip float g->drawarc(pens::red,10,10,100,50,90,90);//pot fi si valori de tip float g->drawstring("drawarc",f,brushes::blue,120,35);//scrie in punctul dat Rectangle r(10,70,100,50); g->drawellipse(gcnew Pen(Color::Green,4),r);//sau g- >DrawEllipse(Pens::Red,10,70,100,50);pot fi si valori de tip float g->fillellipse(gcnew SolidBrush(Color::Yellow),r);//sau g- >FillEllipse(new SolidBrush(Color::Yellow),10,70,100,50);pot fi si valori de tip float 9
g->drawstring("drawellipse FillEllipse",f,Brushes::Blue, RectangleF(120,70,100,50));//scrie in zona data g->fillellipse(gcnew TextureBrush(bm),r); StringFormat ^sf=gcnew StringFormat(); sf->alignment=stringalignment::center; g->drawstring("fillellipse cu TextureBrush",f,Brushes::Blue,RectangleF(r.X+110,r.Y,100,50),sf);//am folosit si formatari pentru text g->drawrectangle(gcnew Pen(Color::Blue,4),r); g->fillrectangle(gcnew SolidBrush(Color::Red),r); g->drawstring("drawrectangle FillRectangle",f,Brushes::Blue,RectangleF(r.X+110,r.Y,120,50)); g->fillrectangle(gcnew TextureBrush(bm),r); g->drawstring("fillrectangle cu TextureBrush",f,Brushes::Blue, RectangleF(r.X+110,r.Y,120,50)); r.x=260; r.y=10; g->drawpie(gcnew Pen(Color::Blue,4),r,10,340); g->fillpie(gcnew SolidBrush(Color::Red),r,10,340); g->drawstring("drawpie FillPie",f,Brushes::Blue, g->drawline(gcnew Pen(Color::Cyan,3),r.X,r.Y,r.X+100,r.Y+50);//g->DrawLine(new Pen(Color::Cyan,3),Point(r.X,r.Y),Point(r.X+100,r.Y+50));-pot fi si valori de tip float g->drawstring("drawline",f,brushes::blue, Point P1(r.X+3,r.Y+35),P2(r.X+50,r.Y+25),P3(r.X+90,r.Y+5),P4(r.X+99,r.Y+49); g->drawbezier(gcnew Pen(Color::Red,2),P1,P2,P3,P4); g->drawstring("drawbezier",f,brushes::blue, array<point>^ P={Point(r.X+3,r.Y+35),Point(r.X+50,r.Y+25),Point(r.X+90,r.Y+5),Point(r.X+7 9,r.Y+29),Point(r.X+99,r.Y+49)}; g->drawpolygon(gcnew Pen(Color::Red,2),P); g->fillpolygon(gcnew SolidBrush(Color::Blue),P); g->drawstring("drawpolygon FillPolygon",f,Brushes::Blue, g->drawimage(bm,r); 10
g->drawstring("drawimage (complet)",f,brushes::blue, r.x=480; r.y=10; g->drawimage(bm,r,30,30,80,40,graphicsunit::pixel); g->drawstring("drawimage (partial)",f,brushes::blue, g->drawimage(bm,r,110,30,-80,40,graphicsunit::pixel); g->drawstring("drawimage (simetrie Oy)",f,Brushes::Blue, g->drawimage(bm,r,30,70,80,-40,graphicsunit::pixel); g->drawstring("drawimage (simetrie Ox)",f,Brushes::Blue, g->drawimage(bm,r,110,70,-80,-40,graphicsunit::pixel); g->drawstring("drawimage (simetrie Ox si Oy)",f,Brushes::Blue, RectangleF(r.X+110,r.Y,100,60)); r.y+=60; array<point> ^Q={Point(r.X+3,r.Y+25),Point(r.X+60,r.Y+5),Point(r.X+40,r.Y+45)}; g->drawimage(bm,q);//cu trei puncte ce descriu trei dintre punctele unui paralelogram g->drawstring("drawimage (vector puncte)",f,brushes::blue, RectangleF(r.X+110,r.Y,120,50)); bm->rotateflip(rotatefliptype::rotate90flipx); r.y+=60; g->drawimage(bm,r); g->drawstring("drawimage (RotateFlip)",f,Brushes::Blue, } 11