zoukankan      html  css  js  c++  java
  • C#-gdi画图,双缓冲画图,Paint事件的触发---ShinePans

    在使用gdi技术画图时,有时会发现图形线条不够流畅,或者在改变窗口大小时会闪烁不断的现象.(Use DoubleBuffer to solve it!)

                                                                                                                                                                                                                                         

    1.线条不流畅:窗口在重绘时自身重绘与图形重绘之间存在时间差,导致二者图像显示不协调

    2.改变窗口大小不流畅:重绘时自身背景颜色与图形颜色频繁交替,造成视觉上的闪烁

          以下,用四个图形样例解决问题 :贝塞尔曲线,圆形,矩形,不规则图形

     思路:首先用Bitmap类的构造方法创建一个位图实例,然后通过调用Graphics类FromImage方法创建画布对象,最后调用Grapgics类的DrawImage方法来实如今窗口上绘制图形.

    public Bitmap(int width,int height); //width 定义位图的宽度  height 定义位图的高度

    Bitmap lacalBitmap =new Bitmap(CilentRectangle.Width,CilentRectangle.Height); //创建一个与窗口工作区大小同样的位图实例


    public static Graphics FromImage(Image image);// image:Image类的子类的实例引用 

    Bitmap localBitmap=new Bitmap(CilentRectangle.Width,CilentRectangle.Height) //创建位图实例


    public void DrawImage(Image image,int x,int y);    // image:要绘制的图像  x:绘制的图像的左上角 x坐标 y:左上角y坐标

    Graphics g=e.Graphics;//获取窗口画布

    g.DrawImage(localBitmap,0,0);  //在窗口中绘制出内存中的图像



    实现:因为Paint被 .net隐藏,我们须要在窗口代码中加上自己的Paint事件中绘制窗口

                this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);

     private void InitializeComponent()
            {
                this.SuspendLayout();
                // 
                // Form1
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(388, 325);
                this.MaximizeBox = false;
                this.MinimizeBox = false;
                this.Name = "Form1";
                this.Text = "双缓冲技术画图";
                this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);

                this.ResumeLayout(false);
            }

     

    this.Paint+=new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);


    源码:
                                                                                                                                                                                                                                                                                                                       
    Form1.cs:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Drawing.Drawing2D;
    
    namespace DoubleBuffer
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Paint(object sender, PaintEventArgs e)
            {
                Bitmap localBitmap = new Bitmap(ClientRectangle.Width, ClientRectangle.Height);
                //创建位图实例
                Graphics bitmapGraphics = Graphics.FromImage(localBitmap);
                bitmapGraphics.Clear(BackColor);
                bitmapGraphics.SmoothingMode = SmoothingMode.AntiAlias;
                PaintImage(bitmapGraphics);
                Graphics g = e.Graphics;//获取窗口画布
                g.DrawImage(localBitmap, 0, 0); //在窗口的画布中绘画出内存中的图像
                bitmapGraphics.Dispose();
                localBitmap.Dispose();
                g.Dispose();
            }
            private void PaintImage(Graphics g)
            {
                //画图
                GraphicsPath path = new GraphicsPath(new Point[]{ new Point(100,60),new Point(350,200),new Point(105,225),new Point(190,ClientRectangle.Bottom),
                    new Point(50,ClientRectangle.Bottom),new Point(50,180)}, new byte[]{
                        (byte)PathPointType.Start,
                        (byte)PathPointType.Bezier,
                        (byte)PathPointType.Bezier,
                        (byte)PathPointType.Bezier,
                        (byte)PathPointType.Line,
                        (byte)PathPointType.Line});
                PathGradientBrush pgb = new PathGradientBrush(path);
                pgb.SurroundColors = new Color[] { Color.Green, Color.Yellow, Color.Red, Color.Blue, Color.Orange, Color.LightBlue };
                g.FillPath(pgb, path);
                g.DrawString("双缓冲画图", new Font("宋体", 18, FontStyle.Bold), new SolidBrush(Color.Red), new PointF(110, 20));
                g.DrawBeziers(new Pen(new SolidBrush(Color.Green),2),new Point[] {new Point(120,100),new Point(120,120),new Point(120,100),new Point(120,150)});
                g.DrawArc(new Pen(new SolidBrush(Color.Blue), 5), new Rectangle(new Point(120, 170), new Size(60, 60)), 0, 360);
                g.DrawRectangle(new Pen(new SolidBrush(Color.Orange), 3), new Rectangle(new Point(240, 260), new Size(90, 50)));
            }
    
         
        }
    }
    

    Form1设计:
    namespace DoubleBuffer
    {
        partial class Form1
        {
            /// <summary>
            /// 必需的设计器变量。
            /// </summary>
            private System.ComponentModel.IContainer components = null;
    
            /// <summary>
            /// 清理全部正在使用的资源。
            /// </summary>
            /// <param name="disposing">假设应释放托管资源,为 true;否则为 false。</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
            #region Windows 窗口设计器生成的代码
    
            /// <summary>
            /// 设计器支持所需的方法 - 不要
            /// 使用代码编辑器改动此方法的内容。
            /// </summary>
            private void InitializeComponent()
            {
                this.SuspendLayout();
                // 
                // Form1
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(388, 325);
                this.MaximizeBox = false;
                this.MinimizeBox = false;
                this.Name = "Form1";
                this.Text = "双缓冲技术画图";
                this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
                this.ResumeLayout(false);
    
            }
    
            #endregion
        }
    }
    


    Program.cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    
    namespace DoubleBuffer
    {
        static class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }
        }
    }
    




    当变化窗口时,会导致图像出现变形,可把窗口属性中的ResizeReDrae 设置为 true


                                                                                                                      =                                                               

  • 相关阅读:
    struct xxx enum(在class下,在static void Main上)
    集合( Stack / Queue / Hashtable 都没有索引)
    集合(ArrayList)
    数组(for 循环+等量代换)
    类型(Math 、Datetime 、random )
    语句(语句分类及if语句)
    运算符分类、优先级
    基本类型转换及练习
    语言基础(项目结构、数据类型、变量、常量)
    进制转换(二进制、八进制、十进制与十六进制之间的相互转换)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/3956833.html
Copyright © 2011-2022 走看看