piirtofunktiot ja ikkunan päivittäminengrako/2008/luennot/piirtofunktiot.pdf · gdi graphical...
Post on 07-Jul-2020
4 Views
Preview:
TRANSCRIPT
Piirtofunktiot ja ikkunanpäivittäminen
Juha Järvensivujuha.jarvensivu@tut.fi
2008
GDIGraphical Device Interface
Graphical Device Interface (GDI)
GDI+
• Parannettu versio GDI:stä (windows XP)• Toteutus .NET:ssä wrapperiluokkien avulla
– Graphics object
private void Form1_Paint(object sender,System.Windows.Forms.PaintEventArgs pe)
{Graphics g = pe.Graphics;
}
Pen
• GDI-objekti reunaviivojen piirtämiseen• System.Drawing.Pen
Graphics g = pe.Graphics;Pen myPen;
myPen = new Pen(Color.Blue);g.drawRectangle(pen,100,50,80,40);myPen.Dispose();
Pen
Graphics g = pe.Graphics;Pen myPen;myPen = new Pen(Color.Blue);myPen.Width = 3;myPen.DashStyle = DashStyle.Dot;g.drawRectangle(pen,100,50,80,40);myPen.Dispose();
Brush
• GDI-objekti alueiden maalaamiseen• System.Drawing.Brush
Graphics g = pe.Graphics;Brush b = new SolidBrush(Color.Blue);g.FillRectangle(b, 120, 20, 50, 50);b.Dispose();
System.Drawing2Dusing System.Drawing.Drawing2D;
Graphics g = e.Graphics;
LinearGradientBrush b = newLinearGradientBrush(new Point(0, 0),new Point(100, 100),Color.Red, Color.Blue);
g.FillRectangle(b, 10, 10, 100, 100);
Graphicspathusing System.Drawing.Drawing2D;
Point[] points = {new Point(40, 60),new Point(50, 70),new Point(30, 90)};
GraphicsPath path = new GraphicsPath();
path.StartFigure(); // Start the first figure.path.AddArc(175, 50, 50, 50, 0, -180);path.AddLine(100, 0, 250, 20);// First figure is not closed.
path.StartFigure(); // Start the second figure.path.AddLine(50, 20, 5, 90);path.AddCurve(points, 3);path.AddLine(50, 150, 150, 180);path.CloseFigure(); // Second figure is closed.
e.Graphics.DrawPath(new Pen(Color.FromArgb(255, 255, 0, 0), 2), path);
Color
• GDI-objekti värin määrittämiseen– Tukee myös läpinäkyvyyttä (alpha)
• System.Drawing.Color
Color red1 = Color.Red;// Alpa, red, green, blueColor red2 = Color::FromArgb(0,255,0,0);
Värin kysyminen käyttäjältä
ColorDialog dlg = newColorDialog();
dlg.Color = Color.Red;
if(dlg.ShowDialog() ==DialogResult.OK)
{Color selected = dlg.Color;
}
Bitmap
• GDI-objekti kuvan piirtämiseen• System.Drawing.Bitmap
String filename = "C:\\Documents and Settings\\AllUsers\\Documents\\My Pictures\\SamplePictures\\Sunset.jpg";
Bitmap bitmap = new Bitmap(filename);e.Graphics.DrawImage(bitmap,new Point(0,0));
Font
• System.Drawing.Font
FontFamily fontFamily = newFontFamily("Arial");
Font font = new Font( fontFamily, 16,FontStyle.Regular, GraphicsUnit.Pixel);
Järjestelmäfontti (system font)
• Oletusfontti, jota käytetään mikäli fonttia eierikseen valita– Esim ikkunoiden otsikoissa
• Fontin koko riippuu esimerkiksikäyttöjärjestelmän asetuksista (large font asetus)
• Ei yleensä muutu suorituksen aikana, joten riittääettä fontin koon selvittää sovelluksenkäynnistysvaiheessa.
Tekstin piirtäminenvoid Form1_Paint(object sender,
PaintEventArgs e){
Brush b = new SolidBrush(Color.Blue);
FontFamily fontFamily = newFontFamily("Arial");
Font font = new Font(fontFamily, 16,FontStyle.Regular, GraphicsUnit.Pixel);
Point p = new Point(10,10);e.Grapihcs.DrawString("Hello world",font, b, p);
}
Wrapped Textstring text1 = "Draw text in a rectangle by passing a RectF to the DrawString
method.";Font font1 = new Font("Arial", 12, FontStyle.Bold, GraphicsUnit.Point);RectangleF rectF1 = new RectangleF(30, 10, 100, 122);e.Graphics.DrawString(text1, font1, Brushes.Blue, rectF1);e.Graphics.DrawRectangle(Pens.Black, Rectangle.Round(rectF1));
Fontin kysyminen käyttäjältäFontDialog fdlg = new FontDialog();fdlg.ShowColor = true;fdlg.Font = textBox1.Font;fdlg.Color = textBox1.ForeColor;
if(fdlg.ShowDialog() !=DialogResult.Cancel )
{textBox1.Font = fdlg.Font ;textBox1.ForeColor = fdlg.Color;
}
GDI-tietorakenteita
• namespace System.Drawing;– Point– Size– Rectangle
Antialiasing
myGraphics.SmoothingMode = SmoothingMode.AntiAlias;
myGraphics.DrawLine(myPen, 0, 0, 12, 8);
ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_fxmclignrl/html/810da1a4-c136-4abf-88df-68e49efdd8d4.htm
Piirtopinta
Device context (piirtopinta)
• GDI:n ylläpitämä windowsin sisäinentietorakenne, joka sisältää piirtopintaanliittyviä atribuutteja, kuten väri ja fonttitekstin piirrossa
• Piirtopintoja– Näyttö (Display)– Tulostin (Printer)– Muisti (Memory, Bitmap)
Device context (piirtopinta)
• Matalan tason toteutus
Pyydetäänkäyttöjärjestelmältäpiirtopinnan kahva
SuoritetaanpiirtotoiminnotGDI-funktioilla
Vapautetaanpiirtopinta, jonka
jälkeen kahva ei oleenää käyttökelpoinen
Asetetaanpiirtopintaan
tarvittavat asetukset(esim kynä)
Esimerkki (winapi)HDC hdc;PAINTSTRUCT ps;// Pyydetään kahva piirtopintaanhdc = BeginPaint(hWnd, &ps);// Asetetaan objekti piirtopintaanHBRUSH old = SelectObject(hdc,
GetStockObject(GRAY_BRUSH));// Piirretään suorakulmio GDI-rajapinnan funktiollaRectangle(hdc,0,0,100,100);// Asetetaan vanha sivellin takaisinSelectObject(hdc,old);// Vapautetaan piirtopintaEndPaint(hWnd,&ps);
Paint sanoma ja ikkunanpäivittäminen
WM_PAINT
• Sovellus saa WM_PAINT sanoman kunjärjestelmä lähettää ikkunanpäivityspyynnön
• Omassa sovelluksessa ei kutsutapiirtofunktiota suoraan, vaan aiheutetaanWM_PAINT sanoma, jos ikkuna pitääpäivittää– InvalidateWindow + UpdateWindow
Esimerkkipublic Form1(){
this.MouseMove += new MouseEventHandler(Form1_MouseMove);this.Paint += new PaintEventHandler(Form1Paint);
}
void Form1_MouseDown(object sender, MouseEventArgs e){
x = e.X;y = e.Y;this.Invalidate();this.Update();
}
void Form1Paint(object sender, PaintEventArgs e){
e.Graphics.DrawRectangle(Pens.Blue, x, y, 100, 100);}
Tuplapuskurointi
• Vähentää ikkunan välkkymistä• Lisää muistinkulutusta• Ei oletuksena päällä formissa
– Form1.DoubleBuffered = false;
Koordinaatisto
Koordinaatisto
• Fyysiset koordinaatit– fyysinen yksikkö yksi kuvapiste,
pikseli– pikseli = pienin laitteen erottama
kuvan mitta
• Loogiset koordinaatit– loogiset yksiköt esitetty
mittayksikköinä
Graphics.PageUnit
• Kertoo mitä yksikköä piirrossa käytetään• GraphicsUnit
– Display– Document (1/300 inch)– Inch– Millimeter– Pixel– Point (1/72 inch)
Graphics.TranslateTransform
• Muuttaa origon paikkaa koordinaatistossa
Graphics g = e.Graphics;Rectangle r = new Rectangle(10, 10, 50, 50);g.FillRectangle(Brushes.Red, r);g.TranslateTransform(50, 50);g.FillRectangle(Brushes.Blue, r);
Graphics.PageScale• Asettaa skaalauskertoimen
– world unit page unit
Graphics g = e.Graphics;Rectangle r = new Rectangle(10, 10, 50, 50);g.FillRectangle(Brushes.Red, r);g.PageScale = 2;g.FillRectangle(Brushes.Blue, r);
Clipping
• Keino rajata alue, jolle piirto halutaantapahtuvan
• Alueen ulkopuolelle jäävä osa jätetäänpiirtämättä
Graphics g = e.Graphics;Rectangle r = new Rectangle(10, 10,100, 100);g.SetClip(new Rectangle(10, 10, 50, 50));g.FillEllipse(Brushes.Red, r);
Ikkunan päivittämisenproblematiikka
• Milloin päivitetään?• Mitä päivitetään?• Miten päivitetään?
Milloin päivitetään?
• Kun ohjelma itse haluaa päivitystä– Ei kutsuta itse ikkunan päivitysfunktiota, vaan
aiheutetaan WM_PAINT sanoma– Invalidate + Update– Refresh
• Kun käyttöjärjestelmä lähettää päivityspyynnön– ikkunan koko muuttuu– ikkuna peittyy toisen ikkunan alle– ikkunaa vieritetään
Mitä päivitetään?
• Ikkunan päivittäminen on raskasta– Kannattaa päivittää vain se alue, joka todella
vaatii päivittämistä (Clipping)– Hitaus korostuu erityisesti usein päivitettäessä
• Esim. Pitääkö ikkuna päivittää aina kun hiirtäliikutetaan ikkunan päällä?
• Invalidate– Asettaa ikkunan alueen epäkelvoksi
Miten päivitetään?• Pidä varsinainen piirtometodi mahdollisimman tehokkaana
– Älä suorita piirtometodissa turhaa laskentaa tms.• Tuplapuskurointi (Double buffering)
– Hyödyllinen monimutkaisten piirto-operaatioiden yhteydessä– Ikkunan sisältö piirretään ensin muistiin ja vasta tämän jälkeen
kerralla näytölle• Ikkunan taustan pyyhkiminen
– WM_ERASEBKGND• GDI-objektin vaihtaminen (kynä, sivellin, fontti jne)
– Ota talteen piirtopinnalla oleva vanha objekti– Aseta vanha objekti takaisin piirron jälkeen
Ikkunan koon muuttaminen
• Ikkuna lukitaan koon muutoksen yhteydessä• Jos ikkunaa halutaan päivittää kesken koon
muutoksen, täytyy lukitus purkaa– LockWindowUpdate
• WM_SIZING– Lähetetään useita kertoja ikkunan kokoa muutettaessa
• WM_SIZE– Lähetetään aina kun ikkunan koko on muuttunut
Lähteitä• Using fonts and text
– http://msdn2.microsoft.com/en-us/library/a3a2bads.aspx• System.Drawing namespace
– http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemDrawing.asp
• GDI– http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/winprog/winprog/graphics_device_interface.asp• Device Context
– http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/devcons_0g6r.asp
Lähteitä
• Getting started with Graphics programming– http://msdn2.microsoft.com/en-
us/library/da0f23z7.aspx• Charles Petzold – Programming windows
– Petzold, C. Programming Windows, 5th edition,Microsoft Press 1999.
• Using managed graphics classes– http://msdn2.microsoft.com/en-
us/library/yhez825d.aspx
top related