I wrote a C# program that takes in a directory name, iterates through the files in it in batches of 100, and outputs gifs.
class Program
{
static void Main(string[] args)
{
GifBitmapEncoder encoder = new GifBitmapEncoder();
int i = 0;
int filei = 0;
foreach (string fileName in Directory.GetFiles(args[0]).OrderBy(s => s))
{
i++;
AddFileToBitmap(encoder, fileName);
Console.WriteLine("Added file {0:000}: {1}", i, fileName);
if (i % 100 == 0)
{
string outFile = string.Format("output{0}.gif", filei);
Console.WriteLine("Saving to file: {0}", outFile);
SaveGif(encoder, outFile);
filei++;
encoder.Frames.Clear();
encoder = new GifBitmapEncoder();
GC.Collect();
Console.WriteLine();
}
}
}
static void AddFileToBitmap(GifBitmapEncoder encoder, string fileName)
{
using (Bitmap img = (Bitmap)Bitmap.FromFile(fileName))
{
BitmapSource bitmap = Imaging.CreateBitmapSourceFromHBitmap(
img.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
encoder.Frames.Add(BitmapFrame.Create(bitmap));
}
}
static void SaveGif(GifBitmapEncoder encoder, string fileName)
{
using (FileStream stream = new FileStream(fileName, FileMode.Create))
{
encoder.Save(stream);
}
}
}
When I run it, memory usage starts at ~1MB, grows to ~800MB for the first 100 images; drops to ~400MB and grows to ~1.2GB for the second 100 images; drops to ~800MB and crashes with an out of memory error for the remaining 30 images.
I assume there is a memory leak somewhere, but I can't find it. GifBitmapEncoder
, BitmapSource
, and BitmapFrame
are not IDisposable
so I can't dispose any of those, and I don't see any other variables I use that could be. Maybe img.GetHbitmap()
which returns a IntPtr
?
Any thoughts?
I got the meat of my code from how to create an animated gif in .net.