简体   繁体   English

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

[英]Imagesharp - Still image to fill with an animated gif

I've been continuing to experiment with ImageSharp and looking to do something a bit more clever. 我一直在继续尝试ImageSharp,并希望做一些更聪明的事情。 I have a still png image with a transparent background, and an animated gif image that's bigger or equal to the still image. 我有一个带有透明背景的静止png图像,以及一个大于或等于静止图像的动画gif图像。 The code below is part of an interface I've created which calls a method, ProcessImage and returns as a memory stream to be outputted as an image of any type later on. 下面的代码是我创建的接口的一部分,该接口调用方法ProcessImage并作为内存流返回,稍后将作为任何类型的图像输出。

All is good and it's recognized the frames of the gif image. 一切都很好,并且可以识别gif图像的帧。 However, the frames seem to be lapping with eachother as it progresses instead of the individual frames referencing the initial frame of the still image. 然而,随着帧的进行,这些帧似乎相互重叠,而不是参考静止图像的初始帧的各个帧。

I might be overlooking an obvious error in my code, but how can I prevent each frame from lapping with eachother and having each frame take a copy of the clean slate of the still image and fill the whitespace with each frame of the Animated gif Image? 我可能忽略了代码中的一个明显错误,但是如何防止每个帧彼此重叠并让每个帧都复制静止图像的干净副本,并用gif动画图像的每个帧填充空白?

Below are the references. 以下是参考。 I did have to reduce the size of the gif as the uploads are limited to 2mb 我确实必须减小gif的大小,因为上传文件的大小限制为2mb

Circle - Still Image 圆-静止图像

Thunder - Animated Image 雷霆-动画图像

The Result of the Thunder and Circle Combined 雷电与圆环相结合的结果

Code: 码:

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

Found the solution to the problem. 找到了解决问题的办法。 I needed to clone the source image (the circle) and dispose of it after each frame of the gif. 我需要克隆源图像(圆圈),并在gif的每一帧之后将其丢弃。 I can achieve this via the using statement, which is a convenient way to ensure that objects like imageFrame disposes correctly. 我可以通过using语句来实现这一点,这是确保诸如imageFrame之类的对象正确配置的便捷方法。 After this solution was implemented, the frames no longer lap together. 实施此解决方案后,框架不再重叠在一起。

        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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM