在使用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

=

C#-gdi画图,双缓冲画图,Paint事件的触发---ShinePans的更多相关文章

  1. C#-gdi绘图,双缓冲绘图,Paint事件的触发

    一. 画面闪烁问题与双缓冲技术 1.1 导致画面闪烁的关键原因分析: 1  绘制窗口由于大小位置状态改变进行重绘操作时 绘图窗口内容或大小每改变一次,都要调用Paint事件进行重绘操作,该操作会使画面 ...

  2. c# GDI画图 双缓冲画图分析

    双缓冲绘图分析  1.Windows 绘图原理  我们在 Windows 环境下看到各种元素,如菜单.按钮.窗口.图像,从根本上说,都是“画”出来的.这时的屏幕,就相当于一块黑板,而 Windows ...

  3. VC双缓冲画图技术介绍

    双缓冲画图,它是一种主要的图形图像画图技术.首先,它在内存中创建一个与屏幕画图区域一致的对象,然后将图形绘制到内存中的这个对象上,最后把这个对象上的图形数据一次性地拷贝并显示到屏幕上. 这样的技术能够 ...

  4. Win32双缓冲画图原理

    网上有许多文章讲述了如何使用Visual C++程序实现双缓冲,都是用C++面向对象语言写的,可能对很多没有接触过面向对象语言的C语言初学者来说理解起来有些困难,并且有些好心人也只是把源代码贴上去,不 ...

  5. MFC中利用GDI+进行双缓冲作图的有关设置

    这里只是在遇到实际问题的时候提出的一种解决方法,用以处理闪屏问题. 首先要做的是对GDI的一个设置问题: 在应用程序类中添加一个保护权限数据成员 class C...App: {... private ...

  6. WinForm之GDI手动双缓冲技术

    private void button1_Click(object sender, EventArgs e) { Bitmap bmp = new Bitmap(this.picturebox.Wid ...

  7. GDI+实现双缓冲绘图方法一

    private void Form5_MouseMove(object sender, MouseEventArgs e) { int intOX = rectDrawArea.X; int intO ...

  8. C# GDI+双缓冲技术

    我想有很多搞图形方面的朋友都会用到双缓冲技术的时候,而且有的时候她的确是个头疼的问题.最近我也要用双缓冲技术,程序怎么调试都不合适,当要对图形进行移动时,总是会出现闪烁抖动.在网上找了些资料,说得都不 ...

  9. 简单的GDI+双缓冲的分析与实现

    为什么要使用双缓冲绘制 在进行多图元绘制的时候: 因为是要一个一个画上去,所以每画一个图元,系统就要做一次图形的绘制操作,图形的重绘是很占用资源的,特别当需要重绘的图形数量很多的时候,所造成的消耗就特 ...

随机推荐

  1. C++经典书目索引及资源下载

    C++经典书目索引: 严重申明 : 本博文未经原作者(jerryjiang)同意,不论什么人不得转载和抄袭 ! Essential C++ 中文版 层次:0基础 导读:<Essential C+ ...

  2. SetWindowLong

    SetWindowLong函数介绍 收藏 SetWindowLong函数介绍 SetWindowLong Unicode 函数原型 LONG SetWindowLong(hwnd,nIndex,lNe ...

  3. Delphi XE2 升级项目编译ralease版本,无法添加UAC解决方法

    我今天把一个原来是Delphi2007的工程升级到了Delphi XE2,在编译ralease版本时候,发现无法添加UAC,我觉得可能是升级的原因,随后我用XE2新建了一个工程,但是在编译raleas ...

  4. 一些关于linux 下的jni下问题

    编译的细节我就不写了,主要写一些linux下的注意事项,mask一下错误(太多windows的例子了) 编译教程:http://www.cnblogs.com/youxilua/archive/201 ...

  5. OSGi 学习之路(4) - osgi的模块化 java在模块化的局限性

    底层代码可见性控制 Java提供了private,public,protected和package private(无修饰符)这四种访问控制级别,不过这仅仅提供了底层的OO数据封装特性.包这个概念确实 ...

  6. SDUT Fermat’s Chirstmas Theorem(素数筛)

    Fermat's Chirstmas Theorem Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描写叙述 In a letter ...

  7. Net Core子应用由于配置引起IIS错误500.19

    Asp.Net Core子应用由于配置中重复添加模块会引起IIS错误500.19 ASP.NET Core已经从IIS中解耦,可以作为自宿主程序运行,不再依赖IIS. 但我们还是需要强大的IIS作为前 ...

  8. JDWP

    JPDA(Java Platform Debugger Architecture) 是 Java 平台调试体系结构的缩写,通过 JPDA 提供的 API,开发人员可以方便灵活的搭建 Java 调试应用 ...

  9. [C#基础] 类

    类成员 字段和方法是最重要的类成员类型,字段是数据成员,方法是函数成员 字段 字段是隶属于类的变量 它可以是任何类型,无论是预定义类型还是用户定义类型 和所有变量一样,字段用来保存数据 它们可以被写入 ...

  10. hash应用以及vector的使用简介:POJ 3349 Snowflake Snow Snowflakes

    今天学的hash.说实话还没怎么搞懂,明天有时间把知识点总结写了,今天就小小的写个结题报告吧! 题意: 在n (n<100000)个雪花中判断是否存在两片完全相同的雪花,每片雪花有6个角,每个角 ...