zoukankan      html  css  js  c++  java
  • WinForm中使用GDI+实现滚动动画

      前两天有人问用.NET怎么做类似于心电图的图像控件。我以前也从来没做过,但是感觉应该不是很困难,关键是要知道从哪开始下手。所以当时只是讲了下我的初步想法。

      1.心电图显示的是线,而线则是由多个点组成,所以做这个效果实际上就是画点。

      2.要画点,首先就需要设置参考坐标系,然后根据指定坐标来画点。

      3.静态的点画好之后就要实现动态的效果了,也就是随着时间的推移,将所有的点往一个横向方向上移动,然后在最后面空出地方再补充上新的点。不过这里要注意的是,我们看到的仅仅只是显示区域的点,对于已经移出视野的那些点就可以抛弃了,不然越积越多,内存就要爆了。


      昨天晚上没什么事,就想自己动手实践一下,看看理论与实际之间是否存在很大的差距。

      首先,存放这么多个点需要一个容器,由于显示区域的宽度并没有固定,所以这个容器的容量应该是动态的,比如List<T>。但在初步设想时,我就已经想到了在增加新点的同时,要将不需要的点都去掉,而实现这个功能的首选就是泛型队列(Queue<T>)。当然,如果直接使用它,还是存在三个问题:1.队列是不限制容量的;2.队列不会在容量达到设定的上限时自动弹出多余的元素;3.队列不会自动改变点的横坐标,使点动起来。当然,这些问题都可以使用外部方法解决,但如果能在里面解决,使代码更清晰,不是更好吗?

      基于以上三个原因,我选择了从Queue<T>中派生出一个新类PQueue。对于点,本来在写这篇随便的时候,想简化代码,直接使用System.Drawing.Point结构,后来发现结构是值类型的,在foreach(Point p in PQueue){}的内嵌代码中是不能修改它的属性的,而Queue<T>又没有索引器,连for循环也没法使用。所以最后还是创建了一个类似于Point结构的P类。

    public class P
    {
    public int X { get; set; }
    public int Y { get; set; }
    }
    
    

      对于P类,在真正使用的时候,可以对它的功能进行扩展,增加颜色等属性,使图像看起来更加丰富多彩。

      创建好点的类,再创建PQueue类。

    代码
    public class PQueue : Queue<P>
    {
    //队列的最大容量
    public int MaxCount { get; set; }
    //队列是否已装满
    private bool isFull = false;

    public PQueue(int max)
    {
    MaxCount
    = max;
    }

    //替换父类的Enqueue方法
    new public void Enqueue(P item)
    {
    if (Count == MaxCount)
    {
    if (!isFull)
    isFull
    = true;
    else
    {
    //平移所有点, 图像开始动起来
    foreach (P p in this)
    p.X
    = p.X - 1;
    }
    }
    base.Enqueue(item);
    //在添加新元素时弹出超过MaxCount的元素
    while (Count > MaxCount)
    Dequeue();
    }
    }

      下面就要开始画图了,不过我没有选择直接操作PictureBox,而是单独建了个类,这样使用起来更加方便。

    class Img
    public class Img
    {
    private PQueue pQueue; //要显示的点的队列

    public int Width { get; set; } //显示区域的宽度
    public int Height { get; set; } //显示区域的高度
    public Color BackColor { get; set; } //背景色
    public Color PColor { get; set; } //显示的点的颜色
    public Image Image { get; private set; } //显示的图像

    public Img(int width, int height, Color backcolor, Color pcolor)
    {
    //设定属性的初始值
    Width = width;
    Height
    = height;
    pQueue
    = new PQueue(Width);
    BackColor
    = backcolor;
    PColor
    = pcolor;
    Image
    = new Bitmap(Width, Height);
    }

    /// <summary>
    /// 画图
    /// </summary>
    /// <param name="pheight">要画的点的Y值,它是不变的, 而X值是要随着时间变化的</param>
    public void Draw(int pheight)
    {
    //默认的坐标原点是左上角点, 为了好看, 这里将点翻转了一下
    P p=new P(){X = pQueue.Count - 1, Y = Height - pheight +1};
    pQueue.Enqueue(p);

    Graphics g
    = Graphics.FromImage(Image);
    g.Clear(BackColor);
    using(Pen pen = new Pen(PColor))
    {
    foreach (P p1 in pQueue)
    {
    Point point1
    = new Point(p1.X, p1.Y);
    //一个像素点太小,把它加长一点就能看得更清楚了
    Point point2 = new Point(p1.X, p1.Y + 3);
    g.DrawLine(pen, point1, point2);
    }
    }
    g.Dispose();
    }
    }

      画图的功能已经做好了,剩下的工作就是检验了。在使用以下代码前,现在窗体上放个PictureBox控件,命名为pic,宽度和高度都设为50.

    代码
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
    img
    = new Img(pic.Width, pic.Height, Color.Black, Color.White);
    System.Timers.Timer timer
    = new System.Timers.Timer(50);
    timer.Enabled
    = true;
    timer.Elapsed
    += new System.Timers.ElapsedEventHandler(timer_Elapsed);
    }

    private Img img;
    private int num = 20;
    private int i = 1;

    void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
    img.Draw(num);
    pic.Image
    = img.Image;
    num
    = num + i;
    if (40 == num)
    i
    = -1;
    if (10 == num)
    i
    = 1;
    }
    }

      运行一下,最后可以看到一条运动的波浪线。以上代码仅仅只是实现了最简单的动画效果,其实只要在改造一下,就可以弄成像迅雷等下载工具的悬浮窗的速度显示效果了。

      注:以上代码需要以下引用命名空间:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Windows.Forms;
  • 相关阅读:
    php 导出csv文件
    dns 服务器配置
    ettercap ARP dns 欺骗
    for循环内 执行$ajax(){}
    js 如何生成二维数组
    jquery读取csv文件并用json格式输出
    echo 换行
    cmd命令运行php,php通过cmd运行文件
    Git 常用命令整理
    图像裁剪插件
  • 原文地址:https://www.cnblogs.com/aaa6032/p/1718257.html
Copyright © 2011-2022 走看看