关于GDI+绘图 闪烁的问题 求指教

SomethingJack 2015-03-31 05:29:53
直接看图,如何消除闪烁,百度了一下 提到一个什么双缓冲的概念?测试了一下 好像无法解决我的问题,动态绘制的车辆
...全文
834 40 打赏 收藏 转发到动态 举报
写回复
用AI写文章
40 条回复
切换为时间正序
请发表友善的回复…
发表回复
BitCoffee 2015-10-15
  • 打赏
  • 举报
回复
引用 38 楼 Grey110 的回复:
。自从学会了双缓冲,从此,腰不疼了,腿不酸了,画面也不闪烁了 尽量把绘图代码放到onpaint中,有必要的时候可以用一下GDI,不要用GDI+
肾好.
脱兔05 2015-04-03
  • 打赏
  • 举报
回复
看上去不错哦
SomethingJack 2015-04-01
  • 打赏
  • 举报
回复
枪炮 你没明白我意思,,,我是对于你这个重构的控件有点不理解,所以我不知道该怎么传递参数。 首先我的实际情况中,没有

int X = 50;
 int Y = 50;
 int MoveY = 5;

Y += MoveY;
            if (Y >= this.Height)
                Y = 50;
有的是从设备传递过来的参数,如果我使用你的控件,按照你的DrawRender函数,那么我需要

Graphics gs = this.你重构的PIC控件.CreateGraphics();
                            //gs.Clear(Color.Black);
                            Pen p = new Pen(Color.Red, 10);
                            gs.FillRectangle(new SolidBrush(Color.Black), 0, 0, this.pictureBox1.Width, this.pictureBox1.Height);
                            gs.DrawRectangle(p, 10f, Y0, 1.5f, 10f);
                            gs.DrawRectangle(p, 40f, Y1, 1.5f, 10f);
                            gs.DrawRectangle(p, 80f, Y2, 1.5f, 10f);
                            gs.DrawRectangle(p, 120f, Y3, 1.5f, 10f);
                            gs.DrawRectangle(p, 160f, Y4, 1.5f, 10f);
                            gs.DrawRectangle(p, 200f, Y5, 1.5f, 10f);
                            gs.DrawRectangle(p, 240f, Y6, 1.5f, 10f);
                            gs.DrawRectangle(p, 280f, Y7, 1.5f, 20f);
                            gs.DrawRectangle(p, 320f, Y8, 1.5f, 40f);
                            gs.DrawRectangle(p, 360f, Y9, 1.5f, 10f);
                            gs.DrawRectangle(p, 400f, Y10, 1.5f, 10f);
                            gs.DrawRectangle(p, 440f, Y11, 1.5f, 30f);
                            gs.DrawRectangle(p, 480f, Y12, 1.5f, 10f);
                            gs.DrawRectangle(p, 520f, Y13, 1.5f, 10f);
                            gs.DrawRectangle(p, 550f, Y14, 1.5f, 20f);
                            gs.DrawRectangle(p, 580f, Y15, 1.5f, 10f);
this.pictureBoxEx21.DrawRender(gs);
this.pictureBoxEx21.Render();
想让你看看这样实现对不对 ,因为我修改了一下控件 发现红色快的坐标不是移动 而是连起来了, 就差那么一丢丢,我就完成了。你这个DEMO确实没有闪烁问题
zzyhost 2015-04-01
  • 打赏
  • 举报
回复
你把图画哪了? 双缓冲是Form的,设置双款冲后你要是直接画Form上绝对不闪
john_QQ:2335298917 2015-04-01
  • 打赏
  • 举报
回复
把gs.clear调用去掉,要想擦除之前的方块,采取异或的方式重新画一遍,然后再重新画
本拉灯 2015-04-01
  • 打赏
  • 举报
回复
引用 28 楼 SomethingJack 的回复:
[quote=引用 26 楼 wyd1520 的回复:] 最后那个就是我整的控件。
恩 要baby还得在助我一把,你这个是针对我的DEMO写的控件,我想问一下,结合到我的实际项目中。 我重构这个控件,一个pic上可能有N个红色快,那么我的参数是不是直接从DrawRender函数中传递?? 比如我有15个红色快

Graphics gs = this.pictureBox1.CreateGraphics();
                            //gs.Clear(Color.Black);
                            Pen p = new Pen(Color.Red, 10);
                            gs.FillRectangle(new SolidBrush(Color.Black), 0, 0, this.pictureBox1.Width, this.pictureBox1.Height);
                            gs.DrawRectangle(p, 10f, Y0, 1.5f, 10f);
                            gs.DrawRectangle(p, 40f, Y1, 1.5f, 10f);
                            gs.DrawRectangle(p, 80f, Y2, 1.5f, 10f);
                            gs.DrawRectangle(p, 120f, Y3, 1.5f, 10f);
                            gs.DrawRectangle(p, 160f, Y4, 1.5f, 10f);
                            gs.DrawRectangle(p, 200f, Y5, 1.5f, 10f);
                            gs.DrawRectangle(p, 240f, Y6, 1.5f, 10f);
                            gs.DrawRectangle(p, 280f, Y7, 1.5f, 20f);
                            gs.DrawRectangle(p, 320f, Y8, 1.5f, 40f);
                            gs.DrawRectangle(p, 360f, Y9, 1.5f, 10f);
                            gs.DrawRectangle(p, 400f, Y10, 1.5f, 10f);
                            gs.DrawRectangle(p, 440f, Y11, 1.5f, 30f);
                            gs.DrawRectangle(p, 480f, Y12, 1.5f, 10f);
                            gs.DrawRectangle(p, 520f, Y13, 1.5f, 10f);
                            gs.DrawRectangle(p, 550f, Y14, 1.5f, 20f);
                            gs.DrawRectangle(p, 580f, Y15, 1.5f, 10f);
[/quote] 可以的呀,看你自己的需求,你想一个控件或多个都成。。然后BABY归我了。
SomethingJack 2015-04-01
  • 打赏
  • 举报
回复
引用 26 楼 wyd1520 的回复:
最后那个就是我整的控件。
恩 要baby还得在助我一把,你这个是针对我的DEMO写的控件,我想问一下,结合到我的实际项目中。 我重构这个控件,一个pic上可能有N个红色快,那么我的参数是不是直接从DrawRender函数中传递?? 比如我有15个红色快

Graphics gs = this.pictureBox1.CreateGraphics();
                            //gs.Clear(Color.Black);
                            Pen p = new Pen(Color.Red, 10);
                            gs.FillRectangle(new SolidBrush(Color.Black), 0, 0, this.pictureBox1.Width, this.pictureBox1.Height);
                            gs.DrawRectangle(p, 10f, Y0, 1.5f, 10f);
                            gs.DrawRectangle(p, 40f, Y1, 1.5f, 10f);
                            gs.DrawRectangle(p, 80f, Y2, 1.5f, 10f);
                            gs.DrawRectangle(p, 120f, Y3, 1.5f, 10f);
                            gs.DrawRectangle(p, 160f, Y4, 1.5f, 10f);
                            gs.DrawRectangle(p, 200f, Y5, 1.5f, 10f);
                            gs.DrawRectangle(p, 240f, Y6, 1.5f, 10f);
                            gs.DrawRectangle(p, 280f, Y7, 1.5f, 20f);
                            gs.DrawRectangle(p, 320f, Y8, 1.5f, 40f);
                            gs.DrawRectangle(p, 360f, Y9, 1.5f, 10f);
                            gs.DrawRectangle(p, 400f, Y10, 1.5f, 10f);
                            gs.DrawRectangle(p, 440f, Y11, 1.5f, 30f);
                            gs.DrawRectangle(p, 480f, Y12, 1.5f, 10f);
                            gs.DrawRectangle(p, 520f, Y13, 1.5f, 10f);
                            gs.DrawRectangle(p, 550f, Y14, 1.5f, 20f);
                            gs.DrawRectangle(p, 580f, Y15, 1.5f, 10f);
lincolnandlinda 2015-04-01
  • 打赏
  • 举报
回复
引用 10 楼 SomethingJack 的回复:
我是直接在窗体上画的,代码不多 就几句,如果大家不嫌麻烦 可以做一个模拟测试一下,搞一个timer控件50MS更新一下绘制坐标 第一是在form里增加以下代码

 SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
            SetStyle(ControlStyles.DoubleBuffer, true); //双缓冲
第二是绘制图形 其中一个参数50MS一次.

Graphics gs = this.CreateGraphics();
                            gs.Clear(Color.Black);
                            Pen p = new Pen(Color.Red, 10);
                            gs.DrawRectangle(p, 10f, 50MS参数, 1.5f, 10f);
使用双缓冲不能直接画到Form上, 使用二块内存,在显示第一块内存的时候,向第二块内存中放入图像数据。你这种闪烁的原因就在于直接向Form上画。
本拉灯 2015-04-01
  • 打赏
  • 举报
回复
最后那个就是我整的控件。
本拉灯 2015-04-01
  • 打赏
  • 举报
回复

我要搞BABY搞到手

http://pan.baidu.com/s/1c0cZBLQ


SomethingJack 2015-04-01
  • 打赏
  • 举报
回复
引用 23 楼 wyd1520 的回复:
[quote=引用 22 楼 SomethingJack 的回复:] 。。。这代码你测试过了?重构的控件显示不出来
这不费话么,尽然质疑我的权威。小心BABY跟你分手。[/quote] 我去 怎么在我这里无效 尼玛啊 把你DEMO共享一下 我看看 奇怪了
本拉灯 2015-04-01
  • 打赏
  • 举报
回复
引用 22 楼 SomethingJack 的回复:
。。。这代码你测试过了?重构的控件显示不出来
这不费话么,尽然质疑我的权威。小心BABY跟你分手。
SomethingJack 2015-04-01
  • 打赏
  • 举报
回复
。。。这代码你测试过了?重构的控件显示不出来
本拉灯 2015-04-01
  • 打赏
  • 举报
回复
这么做就绝对不闪了,要利用OnPaint方法才行


 public class PictureBoxEx2 : PictureBox
    {
        public PictureBoxEx2()
        {
            SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
        }


        int X = 50;
        int Y = 50;
        int MoveY = 5;


        public void Render()
        {
            Y += MoveY;
            if (Y >= this.Height)
                Y = 50;
            this.Invalidate();
        }

        private void DrawRender(Graphics gs)
        {
            gs.Clear(Color.Black);
            Pen p = new Pen(Color.Red, 10);
            gs.DrawRectangle(p, X, Y, 5, 30);
            gs.DrawRectangle(p, X + 30, Y, 10, 60);
         
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            base.OnPaint(pe);
            DrawRender(pe.Graphics);
        }
    }


然后在Time_TIck里调用这个

private void timer1_Tick(object sender, EventArgs e)
        {
          
            this.pictureBoxEx21.Render();
        

        }
本拉灯 2015-04-01
  • 打赏
  • 举报
回复


 Graphics gs = pictureBox1.CreateGraphics();
            //gs.Clear(Color.Black);
           
            Pen p = new Pen(Color.Red, 10);
            gs.FillRectangle(new SolidBrush(Color.Black), 0, 0, pictureBox1.Width, pictureBox1.Height);  <-用这样子填充背景就不闪了
            gs.DrawRectangle(p, X, Y, 5, 30);
            gs.DrawRectangle(p, X + 30, Y, 10, 60);
            gs.Dispose();

            Y += Move;
            if (Y >= this.Height)
                Y = 50;

还有我改了PictureBox 窗体控件变成这个 public class PictureBoxEx : PictureBox { public PictureBoxEx() { SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true); } }
  • 打赏
  • 举报
回复
画到画板上,然后贴到窗体中
SomethingJack 2015-04-01
  • 打赏
  • 举报
回复
引用 17 楼 wyd1520 的回复:
R怎么跟顶楼的DEMO不一样。。。还有我看了这个不像你说的那样呀。
- - 顶楼是我实际数据应用,需要跟设备通讯产生的数据参数,DEMO是模拟的过程,你没看到红色快闪烁??
本拉灯 2015-04-01
  • 打赏
  • 举报
回复
R怎么跟顶楼的DEMO不一样。。。还有我看了这个不像你说的那样呀。
SomethingJack 2015-04-01
  • 打赏
  • 举报
回复
那个链接 提取码和地址分开 我打一起了 http://yunpan.cn/cZTpteVPtIWXt(提取码:76b1)
SomethingJack 2015-04-01
  • 打赏
  • 举报
回复
引用 12 楼 wyd1520 的回复:
发个连接呀,看看还留毛邮箱。
你可以看到例子中的红色快在闪烁了 帖子的那个GIF 没有表现的很明白
加载更多回复(20)

110,531

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧