Programování v jazyku C# II. 4.kapitola
Obsah GDI + Vlastní kontrolky 2/37
GDI+ Graphics Device Interface Služba Windows framework poskytuje obalující třídy Umožňuje programování 2D grafiky bez znalosti konkrétního HW umožňuje jednotný přístup k různému HW (obrazovka, tiskárna,...) 3/37
Základní možnosti 2D vektorová grafika čáry, křivky, plnění,... Bitmapová grafika práce s bitmapou bitmapové formáty Typografie vykreslování textu fonty 4/37
Grafický kontext Virtuální plátno zapouzdřen do instance Graphics Možnost získání z PaintEventArgs (obsluha události Paint) private void Form1_Paint (object sender, System.Windows.Forms.PaintEventArgs e) { e.graphics.drawline(new Pen(Color.Red,3),1,1,50,50); } 5/37
Grafický kontext Možnost získání z metody Control.CreateGraphics Graphics g = this.creategraphics(); g.drawline(new Pen(Color.Blue,3),5,1,50,55); z objektu dedícího od Image Graphics g = Graphics.FromImage(pictureBox1.Image); g.drawline(new Pen(Color.Pink,3),1,1,40,40); picturebox1.invalidate(); 6/37
Třída Graphics Funguje jako stavový automat něco nastavím, nastavení zůstává platné, dokud jej nezměním Uložení stavu GraphicsState Graphics.Save() Obnovení stavu Graphics.Restore(GraphicsState) 7/37
Třída Graphics Nastavení aktivní oblasti Region Clip Nastavení kvality SmoothingMode Default, HighSpeed, HighQuality, AntiAlias Nastavení transformacní matice Matrix Transform matice 3x3 8/37
Základní transformace 9/37
Vektorový zápis 10/37
Homogenní souřednice 11/37
Výhody homogenních souřadnic Možnost složit složitější operaci přede a pak přenásobit všechny body M = (R1 T1 R2) A Snazší implementace možnost rozšířit do 3D použití v grafických kartách 12/37
Třída Matrix Definuje transformaci souřadnic pomocí homogenních souřadnic matice 3x3 Možno použít předdefinované metody Multiply (násobení matic - skládání operací) Rotate, Translate, Scale (rotace, posun, měřítko) Možno transformovat body ručně TransformPoints 13/37
Třída PrintDocument Objekt určený pro tisk dokumentu Událost BeginPrint, EndPrint před startem/po skončení tisku Událost PrintPage při tisku aktuální stránky v argumentu předává kontext tiskárny Metoda Print zahajuje vlastní tisk dokumentu Možnost předat dialogům pro nastavení tiskárny, preview... 14/37
Příklad tisku private void printclick (object sender, System.EventArgs e) { PrintDocument doc = new PrintDocument(); doc.printpage += new PrintPageEventHandler(docPrintPage); doc.print(); } private void docprintpage (object sender, PrintPageEventArgs ev) { ev.graphics.drawline(new Pen(Color.Black,1),0,0,10,10); ev.hasmorepages = false; } 15/37
Třída Brush Štetce jakým způsobem se budou vyplňovat oblasti Abstraktní třída Možnosti vytvoření třída Brushes staticky definované jednoduché štětce White, Black... odděděné třídy SolidBrush(Color) HatchBrush(HatchStyle,Color,Color) BitmapBrush(Bitmap) LinearGradientBrush(Point,Point,Color,Color) 16/37
Příklady štětců HatchBrush brush = new HatchBrush(HatchStyle.DarkUpwardDiagonal, Color.Yellow,Color.Black); graphics.fillrectangle(brush,1,1,100,100); Bitmap bitmap = new Bitmap("C:\\windows\\winnt.bmp"); TextureBrush brush = new TextureBrush(bitmap); graphics.fillellipse(brush,1,1,200,200); LinearGradientBrush brush = new LinearGradientBrush(new Point(5,5), new Point(100,10),Color.Red,Color.White); graphics.fillpolygon(brush,new Point[]{ new Point(50,5),new Point(5,100), new Point(100,30)}); 17/37
Třída Pen Pero jak se budou kreslit cáry Možnosti vytvoření třída Pens staticky definovaná jednoduchá pera konstruktory Pen(Color) Pen(Color,float) Pen(Brush) Pen(Brush,float) 18/37
Třída Pen Začátky a konce čáry vlastnost StartCap, EndCap enum LineCap Flat, Round, Square, Triangle... Styl čárkování vlastnost DashStyle enum DashStyle Dash, DashDot, DashDotDot, Dot, Solid... 19/37
Příklady per Pen pen = new Pen(Color.Red,10); pen.startcap = LineCap.Round; pen.endcap = LineCap.RoundAnchor; graphics.drawbezier (pen,20,100,35,20, 75,100,100,20); pen.endcap = LineCap.ArrowAnchor; pen.startcap = LineCap.Round; pen.dashstyle = DashStyle.Dot; pen.dashcap = DashCap.Round; graphics.drawline (pen,10,80,80,10); Bitmap bitmap = new Bitmap ("C:\\windows\\winnt.bmp"); TextureBrush brush = new TextureBrush(bitmap); Penpen = new Pen(brush,50); graphics.drawarc (pen,30,30,90,90,-90,270); 20/37
Kreslení tvarů Graphics.Draw... obrysy Graphics.Fill... vyplněné objekty (uzavřené) Obvykle je třeba štětec či pero a řídící body Otevřené Arc, Bezier, Curve, Line... Uzavřené ClosedCurve, Ellipse, Pie, Polygon, Rectangle... 21/37
Třída GraphicsPath Umožňuje vytvoření složitějšího tvaru Vykreslí jedním perem či štětcem Bezparametrický konstruktor Přidání segmentu Add... Line, Bezier... Uzavření CloseFigure Vykreslení DrawPath, FillPath 22/37
Třída Font Typografie Zapouzdřuje jeden řez písma Rodina (Arial) Velikost (12) Styl (kurzíva) Konstruktor Font (FontFamily, float) Font (string, float)... 23/37
Rodiny písem Dostupné rodiny písem FontFamily[] FontFamily.Families Generické rodiny FontFamily.GenericMonospace Neproporcionální písmo (Courier) FontFamily.GenericSansSerif Bezpatkové písmo (Arial) FontFamily.GenericSerif Patkové písmo (Times) 24/37
Velikost písma Možnost specifikovat jednotky konstruktor Font(FontFamily, float, GraphicsUnit) Pixel, Point, Milimeter... Některé jednotky jsou závislé na zařízení pixel Některé ne milimetry 25/37
Styl písma Font.Style enum FontStyle Bold, Italic, Regular, Underline, Strikeout Některé styly lze kombinovat Příklad Font font = new Font ("Arial",12, FontStyle.Bold FontStyle.Italic FontStyle.UnderLine ) 26/37
Práce s textem Vypsání Textu Graphics.DrawString(string,Font,Brush,float,float) Nastavení kvality Graphics.TextRenderingHint SystemDefault, SingleBitPerPixel, AntiAlias... Zjištění velikosti textu SizeF Graphics.MeasureString(string, Font) 27/37
Třída Metafile Umožňuje zaznamenat/načíst posloupnost grafických primitiv lze měnit velikost vektorové Uložení do souboru.emf Načtení z EMF či WMF Konstruktory Metafile (string) načte ze souboru Metafile (string, IntPtr) prázdný soubor... 28/37
Ukázka použití Metalife Graphics graphics = this.creategraphics(); IntPtr hdc = graphics.gethdc(); Metafile metafile = new Metafile("prvni.emf",hdc); Graphics gf = Graphics.FromImage(metafile); gf.drawellipse(new Pen(Color.Red),5,5,10,10); graphics.releasehdc(hdc); metafile.dispose();... Metafile metafile = new Metafile("prvni.emf"); graphics.drawimage(metafile,0,0,200,200); graphics.drawimage(metafile,0,0,100,100); graphics.drawimage(metafile,0,0,50,50); 29/37
Třída Bitmap Umožňuje zaznamenat/načíst rastrovou grafiku při změně měřítka problém s kvalitou Podpora formátu BMP, JPG, PNG... Konstruktory Bitmap(string) načte ze souboru typ rozezná automaticky Bitmap(int,int) vytvoří bitmapu a nastaví výšku a šírku... 30/37
Operace s bitmapou Kreslení do bitmapy graphics = Graphics.FromImage(image) graphics.draw... Vykreslení bitmapy graphics.drawimage(bitmap,point) graphics.drawimage(bitmap,rectangle) Uložení bitmapy Bitmap.Save(string,ImageFormat) 31/37
Vlastní kontrolky Vytvoření nových kontrolek oddědí se od Control mnoho práce než začne něco dělat pro vykreslení lze použít třída ControlPaint metody pro kreslení standardních win kontrolek Modifikace existujících kontrolek oddědí se od požadované kontrolky upraví se některé metody, aby odpovídaly požadavkům Kompozice existujících kontrolek oddědí se od UserControl nebo Project --> Add User Control 32/37
Kontrolky a designer Uživatelské kontrolky mají automaticky podporu pro design veřejné property lze editovat přímo v MSVS Další informace o chování pomocí atributu BrowsableAttribute má se zobrazit v okně property CategoryAttribute v jaké kategorii se má zobrazit DescriptionAttribute popisek vlastnosti 33/37
Designer [Description("Text kontrolky"), Browsable(true), Category("Appearance")] public string Text { get { return textbox1.text; } set { textbox1.text = value; } } 34/37
Kreslení kontrolky Někdy nevyhovuje standardní vzhled možnost upravit si způsob vykreslování - např.menu... Událost Paint Např. v případě menu vlastnost OwnerDraw nastavit na true události MeasureItem DrawItem 35/37
Příklad kreslení private void menuitem_drawitem (object sender, System.Windows.Forms.DrawItemEventArgs e) { Font font = new Font ("Verdana",10); Rectangle hranice = e.bounds; if(e.state == DrawItemState.NoAccelerator) { e.graphics.fillrectangle(new SolidBrush(Color.FloralWhite), hranice.x,hranice.y,hranice.width,hranice.height +1); e.graphics.fillrectangle (new SolidBrush(Color.Tan), hranice.x,hranice.y,20,hranice.height +1); e.graphics.drawstring(((menuitem)sender).text,font, Brushes.Tan,hranice.X+20,hranice.Y); } else { e.graphics.fillrectangle(new SolidBrush(Color.Wheat), hranice.x,hranice.y,hranice.width -1,hranice.Height -1); e.graphics.fillrectangle(new SolidBrush(Color.Tan), hranice.x,hranice.y,20,hranice.height +1); e.graphics.drawrectangle(new Pen(Color.Tan,1), hranice.x,hranice.y,hranice.width -1,hranice.Height -1); e.graphics.drawstring(((menuitem)sender).text,font, Brushes.Tan,hranice.X +20,hranice.Y); } } private void menuitem_mea sureitem (object sender, System.Windows.Forms.MeasureItemEventArgs e) { e.itemheight = 20; e.itemwidth = 100; } 36/37
Konec 37/37