如何在面板(背景图像)上淡入淡出(淡出过渡)图像?

我正在向我的方法发送不同的图像,我希望为此更改插入一些效果。

如何淡入和淡出图像?

private void ShowImage(Image image, ImageLayout imageLayout, int numberOfSeconds) { try { if (this.image_timer != null) this.KillImageTimer(); this.customer_form.DisplayImage(image, imageLayout); this.image_timer = new Timer(); this.image_timer.Tick += (object s, EventArgs a) => NextImage(); this.image_timer.Interval = numberOfSeconds* 1000; this.image_timer.Start(); } catch { //Do nothing } public void DisplayImage(Image image, ImageLayout imageLayout) { panel1.BackgroundImage = image; panel1.BackgroundImageLayout = imageLayout; } 

Winforms中没有内置的淡入淡出过渡。

所以你需要自己写一个。

我能想到的最简单的一个是使用第二个Panel ,它在第一个Panel上分层,实际上需要第一个Panel ,否则透明效果将无效。

这是设置,使用两个Panels

 public Form1() { InitializeComponent(); pan_image.BackgroundImage = someImage; pan_layer.Parent = pan_image; pan_layer.BackColor = pan_image.BackColor; pan_layer.Size = pan_image.Size; pan_layer.Location = Point.Empty; } 

对于淡入淡出的动画,我使用了Timer 。 这是一个快速的代码示例:

 Timer timer1 = new Timer(); int counter = 0; int dir = 1; // direction 1 = fade-in.. int secondsToWait = 5; int speed1 = 25; // tick speed ms int speed2 = 4; // alpha (0-255) change speed void timer1_Tick(object sender, EventArgs e) { // we have just waited and now we fade-out: if (dir == 0) { timer1.Stop(); dir = -speed2; counter = 254; timer1.Interval = speed2; timer1.Start(); } // the next alpha value: int alpha = Math.Min(Math.Max(0, counter+= dir), 255); button1.Text = dir > 0 ? "Fade In" : "Fade Out"; // fully faded-in: set up the long wait: if (counter >= 255) { timer1.Stop(); button1.Text = "Wait"; timer1.Interval = secondsToWait * 1000; dir = 0; timer1.Start(); } // fully faded-out: try to load a new image and set direction to fade-in or stop else if (counter <= 0) { if ( !changeImage() ) { timer1.Stop(); button1.Text = "Done"; } dir = speed2; } // create the new, semi-transparent color: Color col = Color.FromArgb(255 - alpha, pan_image.BackColor); // display the layer: pan_layer.BackColor = col; pan_layer.Refresh(); } 

我在一个Button中启动它,我也在其中显示当前状态:

 private void button1_Click(object sender, EventArgs e) { dir = speed2; timer1.Tick += timer1_Tick; timer1.Interval = speed1; timer1.Start(); } 

如您所见,我使用了两种可以设置的速度:一种用于控制Timer的速度,另一种用于控制透明度在每个Tick上的变化步骤。

只需将图像PanelBackgroundColor中的Color更改为完全透明并返回,在两者之间等待指定的秒数即可创建效果。

并且效果结束我调用函数changeImage()来更改图像。 如果此函数返回falseTimer停止良好。

我很确定这可以用更干净,更优雅的方式编写,但因为它似乎工作..

更新

  • 对于无闪烁显示,使用双缓冲控件,如此Panel子类:

 class DrawPanel : Panel { public DrawPanel() { DoubleBuffered = true; } } 

以下是changeImage的示例实现:

 bool changeImage() { if (pan_image.BackgroundImage != null) { var img = pan_image.BackgroundImage; pan_image.BackgroundImage = null; img.Dispose(); } pan_image.BackgroundImage = Image.FromFile(imageFiles[index++]); return index < imageFiles.Count; } 

它假定两个类级变量:一个List imageFiles填充了幻灯片放映的图像文件名和int index = 0