c# - 合并两个图像以进行 "fade"过渡并改变不透明度? (C#/PNG)

标签 c# graphics fade

首先,我想建议它不是 THIS 的重复项。问题。至少这是我的看法:)

我想要实现的是一系列“淡入淡出”动画的帧。

我选择两个 PNG 文件(假设它们大小相同),例如:

我想像图形编辑器中的图层一样“模拟”合并它们。我把Pic1放在上面,不透明度为255,Pic2放在下面,不透明度为0,所以一开始我只看到Pic1。然后我改变它们的不透明度,如下所示:

有什么简单的方法吗?

最佳答案

在 winforms 应用程序中,这可以很容易地完成。创建一个具有一些属性的用户控件:

public Image FromImage { get; set; }
public Image ToImage { get; set; }

private float opacity = 1;

现在覆盖 OnPaint

 protected override void OnPaint(PaintEventArgs e)
    {
        if (FromImage != null && ToImage != null)
        {
            ColorMatrix matrix1 = new ColorMatrix();
            matrix1.Matrix33 = opacity;
            ImageAttributes attributes1 = new ImageAttributes();
            attributes1.SetColorMatrix(matrix1, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);


            ColorMatrix matrix2 = new ColorMatrix();
            matrix2.Matrix33 = 1 - opacity;
            ImageAttributes attributes2 = new ImageAttributes();
            attributes2.SetColorMatrix(matrix2, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

            e.Graphics.DrawImage(FromImage, new Rectangle(0, 0, this.Width, this.Height), 0, 0, this.Width,
                                 this.Height, GraphicsUnit.Pixel, attributes1);
            e.Graphics.DrawImage(ToImage, new Rectangle(0, 0, this.Width, this.Height), 0, 0, this.Width,
                                 this.Height, GraphicsUnit.Pixel, attributes2);
        }
        base.OnPaint(e);
    }

现在将一个计时器放到控件上,将其设置为启用,运行时间约为 100 毫秒。处理勾选事件:

private void timer_Tick(object sender, EventArgs e)
    {
        if(opacity == 0)
        {
            this.timer.Stop();
            return;
        }

        this.opacity -= 0.01f;
        this.Invalidate();
    }

瞧。然而,有一点需要注意。这会产生相当不稳定的过渡,可以通过控件构造函数中的这一行来缓解这种情况:

this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint,true);

基于编辑进行更新:您可以将其变成一个实用程序,该实用程序采用 2 个图像,并使用几乎相同的代码将每个步骤输出到一个新图像。类似于:

public class ImageUtility
{
    private Image image1;
    private Image image2;

    public ImageUtility(Image image1, Image image2)
    {
        this.image1 = image1;
        this.image2 = image2;
    }

    public void SaveTransitions(int numSteps, string outDir)
    {
        var opacityChange = 1.0f/(float) numSteps;

        for(float opacity = 1,i=0;opacity>0;opacity-=opacityChange,i++)
        {
            using(var image = new Bitmap(image1.Width,image2.Width))
            {
                Graphics g = Graphics.FromImage(image);
                ColorMatrix matrix1 = new ColorMatrix();
                matrix1.Matrix33 = opacity;
                ImageAttributes attributes1 = new ImageAttributes();
                attributes1.SetColorMatrix(matrix1, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);


                ColorMatrix matrix2 = new ColorMatrix();
                matrix2.Matrix33 = 1 - opacity;
                ImageAttributes attributes2 = new ImageAttributes();
                attributes2.SetColorMatrix(matrix2, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

                g.DrawImage(image1, new Rectangle(0, 0, image1.Width, image1.Height), 0, 0, image1.Width,
                                     image1.Height, GraphicsUnit.Pixel, attributes1);
                g.DrawImage(image2, new Rectangle(0, 0, image2.Width, image2.Height), 0, 0, image2.Width,
                                     image2.Height, GraphicsUnit.Pixel, attributes2);

                image.Save(Path.Combine(outDir,"Image" + i + ".png"),ImageFormat.Png);
            }
        }
    }

用法:

ImageUtility util = new ImageUtility(Image.FromFile(@"C:\path\pic1.png"), Image.FromFile(@"C:\path\pic2.png"));
util.SaveTransitions(100, @"C:\path\output"); // saves 100 images 

关于c# - 合并两个图像以进行 "fade"过渡并改变不透明度? (C#/PNG),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7282073/

相关文章:

java - JButtons 在 paintComponent() 中起作用

jquery - 向下滚动时如何混合背景图像

jquery - Firefox 中 jQuery 淡入/淡出的问题

c# - 将 MVC4 站点部署到 Azure 会导致 ExtensionAttribute 异常

java - 比较不同 JButton 的文本

c# - AJAX 页面的 EpiServer 本地化

java - 如何绘制 Java2D 模拟的一部分而不更改为图像/缓冲区,这样我就不必每次都重新绘制它的基元?

javascript - 在具有不同类的相同元素上使用淡入淡出

c# - 数组和列表与结构的差异

c# - ADO.NET 实体数据模型 BUG