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