190 likes | 630 Views
Graphics GDI+ is the .NET Framework class library for graphical programming. It provides: Drawing surfaces—windows, bitmaps, printers Tools for 2-D drawing—shapes, polygons, curves, brushes, pens Text-drawing features Image and bitmap support—read, draw onto any surface, draw into image
E N D
Graphics GDI+ is the .NET Framework class library for graphical programming. It provides: • Drawing surfaces—windows, bitmaps, printers • Tools for 2-D drawing—shapes, polygons, curves, brushes, pens • Text-drawing features • Image and bitmap support—read, draw onto any surface, draw into image • Print and print preview • Ability to work with any kind of .NET application—WinForm or WebForm
Graphics In order to draw on a surface, we need an object of type Graphicsassociated with the surface. The Graphicsobject: • "Encapsulates" the surface • Provides the "device context" for the surface • Preserves graphics state for the surface • Provides methods for 2D drawing
Clear DrawArc DrawBezier DrawCurve DrawPolygon DrawRectangle DrawString FillClosedCurve DrawElipse DrawIcon FillElipse FillPath DrawImage DrawLine DrawPath DrawPie FillPie FillPolygon FillRectangle FillRegion Some methods of the Graphicsobject:
To draw on a surface, we need the Graphics object for the surface. • Graphics are not persistent, so we need to redraw the image if the surface becomes invalid. • To redraw our picture, we can handle thePaintevent of the form, OR • To redraw our picture, we can override the virtual functionOnPaint, which Forminherits from Control • AnArrayListis a convenient place to store items that need to be redrawn.
Graphics If your form contains controls such as buttons, textboxes, and labels: The controls are redrawn Automatically when the form receives a Paint event. In your Graphics program, you are only responsible for drawing symbol.
Graphics Examples Graphics1 Graphics2 Graphics3 Graphics4
Graphics In the examples shown in class, there were two ways to get the form repainted: • Write a handler for the Paint event and register for the event • Override the OnPaint method that is inherited from the class Control The second approach is the suggested one. It avoids creating a delegate and adding it to the handler. But your code should do this: protected override void OnPaint (PaintEventArgs e) { base.OnPaint(e); ... } This guarantees that any registered delegates receive the event.
Graphics Question: what do you do when you need to redraw the screen? Answer: force a Paint event. Invalidate(); Update(); Causes a paint message to be sent to the control Causes an immediate call to OnPaint. The Invalidate method governs what gets painted or repainted. The Update method governs when the painting or repainting occurs. If you use the Invalidate and Update methods together rather than calling Refresh, what gets repainted depends on which overload of Invalidate you use. The Update method just forces the control to be painted immediately, but the Invalidate method governs what gets painted when you call the Update method.
Graphics To read a bitmap from a file, use the static method FromFileof theImageclass: Image myImage = Image.FromFile(filename); string
Graphics To read a bitmap from a file, use the static method FromFileof theImageclass: Image myImage = Image.FromFile(filename); If you have aGraphicsobjectg, you can draw the image at locationx, ywith: g.DrawImage(myImage, x, y);
How do you get a Graphics object? • When you override the OnPaint method or install a handler for the Paintevent, you will receive a PaintEventArgsobject that has a Graphicsproperty. • To paint on a form (or control) at other times, you can call the form's CreateGraphicsmethod. You should call Disposeon Graphicsobjects that you create. • To draw on a bitmap in memory, you can obtain a Graphicsobject from the static method. Again you would call Dispose.
Dragging Image on the Form • The example shows how to drag an image in the screen • This is a Model/View/Controller example • Model • Maintains the position of the card on the screen • View • Display the card on the screen with the background image. • Controller • Get mouse input, inform the model of changes in position of the card, and adds to the background when a menu item is selected.
class Model { private Image cardImage; private Point location; publicevent System.EventHandler OnCardLocChanged; public Model(){...} public Point CardPos { get {return location;} set { if (location != value) { location.X = value.X; location.Y = value.Y; OnCardLocChanged(this, new EventArgs()); //Fire the event if a new position is set. } } } public Image CardImage { get {return cardImage;} } }
class View { private Point currentLocation, newLocation; private Model model; private Form form; private Graphics g; public View(Model model, Form form) { this.model = model; this.form = form; g = form.CreateGraphics(); model.OnCardLocChanged += new EventHandler(drawView); } publicvoid drawView(object sender, EventArgs e) { Bitmap newImage = (Bitmap) form.BackgroundImage.Clone(); Graphics niG = Graphics.FromImage(newImage); Image image = model.CardImage; newLocation = model.CardPos; niG.DrawImage(image, newLocation.X, newLocation.Y); g.DrawImage(newImage, 0, 0); newImage.Dispose(); niG.Dispose(); } }
publicclass Form1 : System.Windows.Forms.Form { private System.ComponentModel.Container components = null; private System.Windows.Forms.MainMenu mainMenu1; private System.Windows.Forms.MenuItem menuItem1; private System.Windows.Forms.MenuItem AddToBackground; private Model model; private View view; privatebool dragging; private Random r = new Random(); ... }
publicclass Form1 : System.Windows.Forms.Form { ... public Form1() { InitializeComponent(); model = new Model(); view = new View(model, this); //The view knows about the model and the form dragging = false; //We create a bitmap for the background, start with one rectangle, //and set it as the background image for the form. Bitmap bckgnd = new Bitmap(this.ClientSize.Width, this.ClientSize.Height); Graphics g = Graphics.FromImage(bckgnd); SolidBrush br = new SolidBrush(Form1.DefaultBackColor); g.FillRectangle(br, 0, 0, this.ClientSize.Width, this.ClientSize.Height); g.DrawRectangle(new Pen(Color.Black), 100,100,20,20); this.BackgroundImage = bckgnd; br.Dispose(); g.Dispose(); } ... }
//The paint event handler just asks the view to draw the form. privatevoid Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e) { view.drawView(this, new EventArgs()); } //When the mouse goes down, we get the position of the card from the model //and if the mouse is inside, then we start dragging. privatevoid Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) { Rectangle rect = new Rectangle(model.CardPos.X, model.CardPos.Y, model.CardImage.Width, model.CardImage.Height); if (rect.Contains(e.X, e.Y)) dragging = true; }
//If the mouse moves when we are dragging, we update the model to indicate //a new position for the card. The model will let the view know. privatevoid Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) { if (dragging) model.CardPos = new Point(e.X, e.Y); } //It's possible to drag the card off the form. If that happens, we //put it back. privatevoid Form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) { Point pt = model.CardPos; dragging = false; if (pt.X < 0) pt.X = 0; if (pt.X > this.ClientSize.Width - model.CardImage.Width) pt.X = this.ClientSize.Width - model.CardImage.Width; if (pt.Y < 0) pt.Y = 0; if (pt.Y > this.ClientSize.Height - model.CardImage.Height) pt.Y = this.ClientSize.Height - model.CardImage.Height; model.CardPos = pt; }
//This lets us add to the background, just to be sure everything works. //The model is not aware of the background. privatevoid addToBackgroundMenuItem_Click(object sender, System.EventArgs e) { Graphics g = Graphics.FromImage(this.BackgroundImage); int x = r.Next(this.ClientSize.Width - 20); int y = r.Next(this.ClientSize.Height - 20); Pen p = new Pen(Color.Black); g.DrawRectangle(p, x, y, 20, 20); p.Dispose(); g.Dispose(); } }