如何在Windows窗体中的Panel中重新绘制平滑 [英] How re-paint in Panel smooth in windows form

查看:174
本文介绍了如何在Windows窗体中的Panel中重新绘制平滑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何平滑地重新粉刷面板?

How can I repaint a panel in smooth?

我正在使用一个计时器,该计时器每300ms会使面板(panel1.Invalidate();)失效,然后通过panel1_Paint事件将图像添加到该面板中,问题是它看起来像在跳跃,我需要尽可能快地在其上移动一张图像.

I am using a timer that is invalidating the panel(panel1.Invalidate();) every 300ms, and then with the panel1_Paint event I am adding images to that panel the issue is that it looks like is jumping and I need to be moving one image on it as fast as I can.

这是截屏问题的链接:http://screencast.com/t/HdtIV99YN

This is a link of the screen-cast issue: http://screencast.com/t/HdtIV99YN

 private void panel1_Paint(object sender, PaintEventArgs e)
            {
                PaintMapObstacles(e);
                PaintMapStartAndGoal(e);

                if (trayectoryIndex < 1000)
                {
                   MapPoint point =  GetTrayectoryPoint(0, trayectoryIndex);
                   e.Graphics.DrawImage(new Bitmap("robot.jpg"), point.X*squareSize, point.Y*squareSize, 60, 60);
                   trayectoryIndex++;
               }
            }
     private void PaintMapStartAndGoal(PaintEventArgs e)
            {
                MapPoint start = new MapPoint { X = 0, Y = 0 };
                MapPoint goal = new MapPoint { X = 7, Y = 8 };
                   // e.Graphics.DrawImage(new Bitmap("start.jpg"), start.X * squareSize, start.Y * squareSize, 60, 60);
                    e.Graphics.DrawImage(new Bitmap("goal.jpg"), goal.X * squareSize, goal.Y * squareSize, 60, 60);
                    isFirstRun = true;
            }


        private void PaintMapObstacles(PaintEventArgs e)
            {

                foreach (MapPoint mpoint in obstacles.Obstacles)
                {
                    e.Graphics.DrawImage(new Bitmap("obstacle.png"), mpoint.X * squareSize, mpoint.Y * squareSize, 60, 60);  
                }
            }

         private void PanelTimer_Tick(object sender, EventArgs e)
            {

                panel1.Invalidate();
            }

推荐答案

它称为闪烁",当您从头开始重新绘制窗口时,它始终存在.它在您的程序中特别引人注目,因为您的绘画代码效率很低.您会看到绘制了窗户的背景,从而擦除了旧画.然后慢慢将位图绘制回背景.擦除步骤在肉眼可见,并且看起来像闪烁.

It is called "flicker", an artifact that's always around when you repaint a window from scratch. It is especially noticeable in your program because your painting code is so inefficient. You see the window's background getting drawn, erasing the old painting. Then slowly getting the bitmaps drawn back onto the background. The erasure step is visible to the eye and looks like flicker.

闪烁的一般解决方法是双缓冲,首先将窗口内容组成一个位图,然后迅速将位图拖到屏幕上.它是Winforms的内置功能,DoubleBuffered属性将其打开.默认情况下,Panel类未启用双缓冲,它被设计为一个容器控件,除了绘制背景外,它本身不会进行绘制. PictureBox在您的情况下也可以正常工作,默认情况下启用了双缓冲.或者,您可以为Panel类打开双重缓冲,显示在此处.

The general cure for flicker is double-buffering, composing the window content into a bitmap first, then quickly blitting the bitmap to the screen. It is a built-in feature for Winforms, the DoubleBuffered property turns it on. Double-buffering is not enabled by default for the Panel class, it was designed to be a container control that doesn't do painting on its own beyond drawing the background. A PictureBox will work just as well in your case, it has double-buffering enabled by default. Or you can turn on double-buffering for the Panel class, shown here.

您确实希望最终解决绘画代码中的问题,除了它非常缓慢之外,它还可能由于OutOfMemoryException导致程序崩溃.由您使用Bitmap类的方式引起的问题,应在使用它后将其清除.始终对System.Drawing对象使用 using 语句.

You do want to eventually address the problems with your painting code, beyond it being very slow, it can crash your program with an OutOfMemoryException. A problem caused by the way you use the Bitmap class, it should be disposed after you used it. Always use the using statement for System.Drawing objects.

只需创建一次位图,就可以更快地完成它,表单构造器是最好的地方.通过预缩放位图以使其适合网格并注意像素格式,可以使其真正更快地实现. PixelFormat.Format32bppPArgb与几乎任何现代视频适配器的帧缓冲区格式直接兼容,位图可以直接复制到帧缓冲区中,而无需进行转换.比所有其他格式快十倍.转换代码在此处.

You'll make it a lot faster by creating the bitmaps just once, the form constructor is the best place. You make it really fast by prescaling the bitmaps to fit the grid and paying attention to the pixel format. PixelFormat.Format32bppPArgb is directly compatible with the frame buffer format of almost any modern video adapter, the bitmap can be directly copied into the frame buffer without conversion. Ten times faster than all the other formats. Conversion code is here.

这篇关于如何在Windows窗体中的Panel中重新绘制平滑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆