0

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

一切都很好,它可以识别 gif 图像的帧。然而,这些帧似乎随着它的进展而相互重叠,而不是参考静止图像的初始帧的各个帧。

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

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

圆圈 - 静止图像

迅雷 - 动画图像

雷与圆结合的结果

代码:

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

1 回答 1

1

找到了问题的解决方案。我需要克隆源图像(圆圈)并在 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;
于 2017-12-22T16:07:07.117 回答