Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将两个图像合并为“";“褪色”;改变不透明度的过渡?(C#/PNG)_C#_Graphics_Fade_Winforms - Fatal编程技术网

将两个图像合并为“";“褪色”;改变不透明度的过渡?(C#/PNG)

将两个图像合并为“";“褪色”;改变不透明度的过渡?(C#/PNG),c#,graphics,fade,winforms,C#,Graphics,Fade,Winforms,首先,我想说的是,这不是一个重复的问题。至少这是我的看法:) 我想要实现的是一系列帧来“淡入”动画 我选择了两个PNG文件(假设它们大小相同),例如: 我想“模拟”合并它们,就像在图形编辑器中的图层一样。我把Pic1放在顶部,不透明度为255,Pic2放在下面,不透明度为0,所以一开始我只看到Pic1。然后我改变它们的不透明度,如下所示: 有什么简单的方法吗?使用您可以使用的,使用接受参数的重载。该类可以指定对颜色(和alpha)值的操作 ImageAttributes页面上的

首先,我想说的是,这不是一个重复的问题。至少这是我的看法:)

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

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

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

有什么简单的方法吗?

使用您可以使用的,使用接受参数的重载。该类可以指定对颜色(和alpha)值的操作


ImageAttributes
页面上的示例几乎就是您想要的。只需在同一位置绘制原始图像和变换图像,并将颜色矩阵更改为仅更改alpha级别。

在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);
    }
现在在控件上放置一个计时器,将其设置为enabled(启用),运行时间大约为100ms。处理勾号事件:

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 

没有代码,就没有饼干!到目前为止你试过什么?我们是在说WPF吗?赢表格?Silverlight?对不起WinForms。以下是cookie:-我发现了一个稍微不同的例子,并设法自己改变了它。不确定,如果它在数学上是正确的,但它是有效的。不确定我是否理解它-第二个图像在哪里?我想将一个图像淡入另一个图像,并保存动画的每个“帧”。@WRonX-请参阅更新。很容易将相同的代码转换成一个util,将每次转换保存到磁盘。我会检查它,但我想它可能是答案。非常感谢。我的解决方案(在对问题的评论中)在透明PNG上失败,所以我会检查你的。我假设如果我需要预览,我可以强制转换和分配,我的意思是pictureBox1.Image=(Image)Image??你认为这就是答案吗?不要听起来太热情或者其他什么。也许听起来是这样的,因为:1。我的英语不好。2.我通常不太擅长C#来知道这是否是我仅仅阅读代码的意思,而我现在无法检查它(不同的地方,不同的机器)。对不起,如果这冒犯了你,我不是那个意思。我热衷于结束我开始的一切,所以再次:非常感谢!