I recently had the need to convert images to Google's .webp format from .net. There is a .net port of the WebP library available, but it didn't seem to work for me and it seems to be no longer maintained.
So P/Invoke it was. Here's the code I used:
Bitmap source = new Bitmap("Desert.jpg");
BitmapData data = source.LockBits(
new Rectangle(0, 0, source.Width, source.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);
IntPtr unmanagedData;
int size = WebPEncodeBGR(data.Scan0, source.Width, source.Height, data.Stride, 85, out unmanagedData);
byte[] managedData = new byte[size];
Marshal.Copy(unmanagedData, managedData, 0, size);
File.WriteAllBytes("Desert.webp", managedData);
Marshal.FreeHGlobal(unmanagedData); // Doesn't work. How do we free the unmanaged data?
As you can see, all goes swimmingly until it comes to freeing the unmanaged memory allocated by the WebP library. The memory is allocated by malloc() and needs to be freed by calling free(), however you have no access to this from .net.
My solution was to modify the WebP library to provide a WebPFree function, which simply calls the C free(). Calling this instead of Marshal.FreeHGlobal fixes the memory leak.
I've included my modifed WebP binaries as part of a sample project here.
No comments:
Post a Comment