Creating a gif from images using ImageSharp
There are several techniques one can use to create a gif on Windows. You can use FFMPEG. Or you can use Six Labors ImageSharp.
In the following I present to you my solution using ImageSharp:
// Images that will be included in the gif. The duration is in milliseconds
List<(string path, int duration)> images = new List<(string, int)>()
{
//100 => 1 second
("image1.jpg", 100),
("image2.jpg", 150)
};
// The final dimensions of the gif
int width = 500, height = 500;
// Create a blank canvas for the gif
using (var gif = new Image<Rgba32>(width, height))
{
for (int i = 0; i < images.Count; i++)
{
// Load image that will be added
using (var image = Image.Load(images[i].path))
{
// Resize the image to the output dimensions
image.Mutate(ctx => ctx.Resize(width, height));
// Set the duration of the image
image.Frames.RootFrame.Metadata.FrameDelay = images[i].duration;
// Add the image to the gif
gif.Frames.InsertFrame(i, image.Frames.RootFrame);
}
}
// Save an encode the gif
using (var fileStream = new FileStream("result.gif"))
{
gif.SaveAsGif(fileStream);
}
}
You can further optimize the process when you perform the resizing in parallel. We dont want to delete the original images, so a temp directory for the resized images is necessary.
async Task CreateGif(List<(string, path, int duration)> images,
string resultFilePath = "result.gif",
int width = 500,
int height = 500,
string tempPath = "/temp")
{
// Iterate in parallel over the images and wait until all images are processed
await Parallel.ForEach(images, (data, state, index) =>
{
// Exit when an error occurred or the foreach has stopped
if (state.ShouldExitCurrentIteration || state.IsExceptional || state.IsStopped)
{
return;
}
// Load the image
using (var image = Image.Load(data.path))
{
// Resize the image
image.Mutate(ctx => ctx.Resize(width, height));
// Build temp path for image based on index
string resizeTempPath = Path.Combine(temPath, $"{index}.{Path.GetExtension(path)}");
// Save the image
image.Save(resizeTempPath);
}
});
// Iterate over the images to create the gif
for (int index = 0; index < images.Count; i++)
{
// Build path to resized image
string resizeTempPath = Path.Combine(temPath, $"{index}.{Path.GetExtension(images[index].path)}");
// Load the resized image that will be added
using (var image = Image.Load(resizeTempPath))
{
// Set the duration of the image
image.Frames.RootFrame.Metadata.FrameDelay = images[index].duration;
// Add the image to the gif
gif.Frames.InsertFrame(index, image.Frames.RootFrame);
}
}
}
// Save an encode the gif
using (var fileStream = new FileStream(resultFilePath))
{
gif.SaveAsGif(fileStream);
}
// Cleanup temp directory with content
Directory.Delete(temPath, true);
}
Happy coding!
Comments
New Comment
When clicking "Post" you agree to publish your comment publicly and have acknowledged the privacy implications below.
Privacy: The following information will be stored when you post a comment: