很久没发技术文章了啊……被人说装文艺了啊……我在乱说些啥吗………… 当这三幅图片以一定频率直接切换的时候,人们就会看到A貌似是在像右方移动。 那么为什么我们依据这个原理来编程绘制动画的时候会出现闪烁呢?是因为计算机的速度太慢不够给力么?当然不是! 我们如果不加任何处理,就在画布C上进行绘图,那么计算机的处理过程是这样的:
那么这样的过程会对动画产生怎样的影响呢?请看图2: 看出和图1的差别了吧?Step1相当于在原本连续的动画中嵌入了空白的画面,这个空白的画面由于和人眼中原本残留的图像反差非常大,所以便会破坏视觉残留产生的动画,给人的感觉就是,这个动画在不停的闪烁。 于是我们现在知道消除Step 1这个过程带来的影响,就能够避免在绘制的时候发生闪烁,不知道你会不会想,直接把Step 1略过不就得了?但我可以很负责任的告诉你……不行!如果只是单纯的略过Step 1,那么动画就会变成这样: 在视觉上就成了一个拖着残像尾巴运动的动画,相信大家一定见过这个: 那么我现在就可以解释双缓冲是怎样防止闪烁的了。 假如我们希望在屏幕S上展示动画,首先我们需要在内存中建立一个虚拟的画布C,然后我们所有的绘图操作都在C上进行,当绘制动画的一帧完毕后,我们啪唧~把C直接往S上一拍,这样就既不会出现拖尾巴,也不会出现Refresh时的短暂空白了,如下图所示,红色的框就代表那块虚拟的画布: 原理我们都知道了,但是实际应用的时候还是会遇到一些问题,这些问题涉及到C#本身的窗体的绘制机制,不过我们还是能够解决的。 当我们通过这种方法在pictureBox上绘图的时候,特别是pictureBox还存在背景图片的时候。我们就会遇到问题: C# // 初始化画板Bitmap image = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height);// 初始化图形面板Graphics g = Graphics.FromImage(image);// 绘图部分 Begin// ... ...// 绘图部分 EndpictureBox1.CreateGraphics().DrawImage(image, 0, 0); 画布g是透明的,所以在g上绘制后,贴在pictureBox上,背景图片还是会展示出来,但是问题也就来了,由于pictureBox的绘制机制问题,如果我在pictureBox上贴一张透明的图,其效果就是这样的: 不知道读者明白这是什么意思了么……如果将透明的图片贴上去,那其实和直接略掉刚才所说的Step 1别无二异!如果我们想要将之前的内容去除,就不得不再使用pictureBox1.Refresh()方法,而这样的话,显然会导致闪烁,那么该怎么办呢? 网上搜索了很多,也有很多方法,比如将窗体的Double Buffered属性设置为true,或者通过继承或者反射机制,将pictureBox的Double Buffered属性设置为true,但是经过实验,这些方法都不大灵光。于是我开始静下心来思考该怎么绕过这个问题。 其实理清思路后就会发现,我们这个问题所遇到的障碍就是不能影响pictureBox的背景图的展示,所以我们为何不把pictureBox的背景图片也提取出来,作为底层画布呢? 下面是我给出的解决方案: C#
注意我标注的行,就是添加的部分。 |
|
来自: goodwangLib > 《C#图像》