微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 透明图形缓冲区清除?

我目前正在开发一个我必须使用GDI(System.Drawing)的项目.我正在尝试制作一个带有动态neeldes的多功能仪表(一个类似钟表的轮子).

我不想每帧都绘制背景图像(带有所有标记).我现在解决这个问题的方法是将它设置为图形“容器”的背景图像,这是一个面板(请记住这一点,我可能不得不这样做).

那么我画针.针目前每秒更新25次(我可能会优化它,以便它只在必要时更新).但问题是,我必须在开始使用新帧之前清除缓冲区,导致背景图像被缓冲区的背景颜色覆盖.显然我不想要这个.

我已经尝试将缓冲区的背景颜色设置为Color.Transparent,但它根据父级的透明度键(在我的情况下,它变成黑色)给缓冲区一个颜色.

这是我当前用于绘制针的代码(在Wheel类中):

/// <summary>
    /// Draws the wheel and the needles.
    /// </summary>
    public void Draw()
    {
        Graphics.Clear(Color.Transparent);

        // Draws all needles,works fine
        foreach (Needle Ndl in Needles)
        {
            Ndl.Draw(ref this.Graphics);
        }

        // Draws the little circle in the center of the wheel. Looks only.
        Graphics.FillEllipse(new Pen(Color.White).Brush,new Rectangle(120,120,16,16));
    }

是的,我遵循了Stack Overflow规则,我完成了我的作业.其他人通过使用BitBlt每帧绘制图像来解决它,这是我的大脑理解的方法.

我对此非常开放,所以如果你认为我应该使用BitBlt,你知道我在哪里可以找到一些关于它的全面深入的例子,我肯定会用BitBlt来做.当然,如果有不使用BitBlt的解决方案,或者无论如何在这里使用它都没有意义,那会更好.

是否可以使缓冲区的背景透明或者我应采取完全不同的方法

注意:我最好不要使用XNA,因为这个应用程序主要用于简单/旧计算机上的维护,所以我不想与可再发行组件有任何关系.

解决方法

您可以将基本图像放在PictureBox中.然后你的代码可以处理PictureBox的Paint事件来绘制你的针.这样您就不必担心Graphics.Clear()的透明度或运行缓慢:您的代码只需要计算针的位置.

作为一个快速测试,我写了一个小形式的应用程序,创建一个时针(红色),秒针(贪婪)和毫秒手(蓝色).分针得不到尊重,因此未显示.背景是在GIMP中创建的黑色圆角矩形的图像.

为了模拟你的环境,我添加一个间隔为10毫秒(100周期/秒)的计时器.处理事件Timer.Tick时,强制重绘PictureBox.

我手工编辑代码只留下毫秒手的代码

public Form1()
    {
        InitializeComponent();

        pictureBox1.Paint += new PaintEventHandler(pictureBox1_Paint);

        Center = new PointF((float)pBox1.Width / 2,(float)pBox1.Height / 2);

        MillisecondLength = (float)pBox1.Width / 4;  //length of millisecond hand

        timer1.Interval = 10;  
        timer1.Enabled = true;
        timer1.Tick += new EventHandler(timer1_Tick);
    }

    PointF Center;

    float MillisecondLength;
    Pen MillisecondsPen = new Pen(Brushes.Blue,(float)3);

    double HALF_PI = Math.PI / 2;
    double TWO_PI = 2 * Math.PI;

    double millisecondHandAngle(DateTime dt)
    {
        //12 o'clock is at the top! (- PI / 2)
        return TWO_PI * dt.Millisecond / 1000 - HALF_PI;
    }

    void pBox1_Paint(object sender,PaintEventArgs e)
    {
        DateTime dt = DateTime.Now;         
        double mangle = millisecondHandAngle(dt);

        Sizef millisecondOffset = new Sizef(
            (float)(MillisecondLength * Math.Cos(mangle)),(float)(MillisecondLength * Math.Sin(mangle))
        );

        PointF endMillisecond = PointF.Add(Center,millisecondOffset);

        e.Graphics.DrawLine(MillisecondsPen,Center,endMillisecond);
    }

    void timer1_Tick(object sender,EventArgs e)
    {
        pBox1.Invalidate();
    }

虽然它没有显示在该代码中,但我添加一个System.Diagnostics.Stopwatch和一个计数器变量来计算实际帧速率,这在我的旧笔记本电脑上达到峰值,大约为64帧/秒.即使您将计时器间隔设置得非常小,也会有最大重绘率.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐