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

时间:2015-02-17 14:33:21

标签: c# winforms timer

我正在向我的方法发送不同的图像,我想为这种变化插入一些效果。

我如何淡入和淡出图像?

 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;
    }

1 个答案:

答案 0 :(得分:4)

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

所以你需要自己写一个。

我能想到的最简单的一个使用第二个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(); } 。这是一个快速的代码示例:

private void button1_Click(object sender, EventArgs e)
{

    dir = speed2;
    timer1.Tick += timer1_Tick;
    timer1.Interval = speed1;
    timer1.Start();
}

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

Timer

正如您所看到的,我使用了您可以设置的两种速度:一种用于控制Tick的速度,另一种用于控制透明度在每个Color上更改的步骤。

只需将BackgroundColor从图像Panel的{​​{1}}更改为完全透明并返回,在两者之间等待指定的秒数即可创建效果。

效果结束我调用函数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<string> imageFiles填充了幻灯片放映的图像文件名和int index = 0