Imagesharp - 用动画 gif 填充的静止图像

Imagesharp - Still image to fill with an animated gif

我一直在继续试验 ImageSharp 并希望做一些更聪明的事情。我有一个带有透明背景的静止 png 图像,以及一个大于或等于静止图像的动画 gif 图像。下面的代码是我创建的接口的一部分,它调用方法 ProcessImage 和 returns 作为内存流,稍后将作为任何类型的图像输出。

一切正常,可以识别gif图片的帧。然而,帧似乎在前进时相互重叠,而不是各个帧引用静止图像的初始帧。

我可能忽略了我的代码中的一个明显错误,但是我怎样才能防止每一帧相互重叠并让每一帧复制静止图像的干净石板并填充动画 gif 图像的每一帧都有空白?

参考资料如下。我确实不得不减小 gif 的大小,因为上传限制为 2mb

Circle - Still Image

Thunder - Animated Image

The Result of the Thunder and Circle Combined

代码:

    public MemoryStream ProcessImage()
    {
        MemoryStream ms = new MemoryStream();
        const int min = 128; // Grey midpoint
        using (var img = Image.Load(ImagePath))
        using (var texture = Image.Load(Texture))
        {
            if (img.Width > texture.Width || img.Height > texture.Height)
            {
                throw new InvalidOperationException("Image dimensions must be less than or equal to texture dimensions!");
            }

            Image<Rgba32> animated = new Image<Rgba32>(img.Width, img.Height);
            ImageFrame<Rgba32> imageFrame = img.Frames[0];
            foreach (var Frame in texture.Frames)
            {
                ImageFrame<Rgba32> currentFrame = imageFrame;
                for (int y = 0; y < currentFrame.Height; y++)
                {
                    for (int x = 0; x < currentFrame.Width; x++)
                    {
                        var pixel = currentFrame[x, y];
                        if (pixel.R >= min && pixel.G >= min && pixel.B >= min && pixel.A >= min)
                        {
                            currentFrame[x, y] = Frame[x, y];
                        }
                    }
                }
                animated.Frames.AddFrame(currentFrame);
            }
            animated.SaveAsGif(ms);
            return ms;
        }
    }

找到问题的解决方法。我需要克隆源图像(圆圈)并在 gif 的每一帧之后处理它。我可以通过 using 语句实现此目的,这是确保正确处理 imageFrame 等对象的便捷方式。实施此解决方案后,框架不再重叠。

        MemoryStream ms = new MemoryStream();
        const int min = 128; // Grey midpoint
        using (var img = Image.Load(ImagePath))
        using (var texture = Image.Load(Texture))
        {
            if (img.Width > texture.Width || img.Height > texture.Height)
            {
                throw new InvalidOperationException("Image dimensions must be less than or equal to texture dimensions!");
            }

            Image<Rgba32> animated = new Image<Rgba32>(img.Width, img.Height);
            foreach (var Frame in texture.Frames)
            {
                using (var imageFrame = img.Frames.CloneFrame(0))
                {
                    Image<Rgba32> currentFrame = imageFrame;
                    for (int y = 0; y < currentFrame.Height; y++)
                    {
                        for (int x = 0; x < currentFrame.Width; x++)
                        {
                            var pixel = currentFrame[x, y];
                            if (pixel.R >= min && pixel.G >= min && pixel.B >= min && pixel.A >= min)
                            {
                                currentFrame[x, y] = Frame[x, y];
                            }
                        }
                    }
                    animated.Frames.AddFrame(currentFrame.Frames.First());
                }
            }
            GifEncoder GifEncode = new GifEncoder();
            animated.SaveAsGif(ms);
            return ms;