Skip to content

Instantly share code, notes, and snippets.

@nuitsjp
Last active October 17, 2016 08:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nuitsjp/801325e2f4946b4e59634ebb28cf2499 to your computer and use it in GitHub Desktop.
Save nuitsjp/801325e2f4946b4e59634ebb28cf2499 to your computer and use it in GitHub Desktop.
Convert System.Windows.Media.BitmapSource to System.Drawing.Bitmap
public static Bitmap ToBitmap(this BitmapSource bitmapSource, PixelFormat pixelFormat)
{
int width = bitmapSource.PixelWidth;
int height = bitmapSource.PixelHeight;
int stride = width * ((bitmapSource.Format.BitsPerPixel + 7) / 8); // 行の長さは色深度によらず8の倍数のため
IntPtr intPtr = IntPtr.Zero;
try
{
intPtr = Marshal.AllocCoTaskMem(height * stride);
bitmapSource.CopyPixels(new Int32Rect(0, 0, width, height), intPtr, height * stride, stride);
using (var bitmap = new Bitmap(width, height, stride, pixelFormat, intPtr))
{
// IntPtrからBitmapを生成した場合、Bitmapが存在する間、AllocCoTaskMemで確保したメモリがロックされたままとなる
// (FreeCoTaskMemするとエラーとなる)
// そしてBitmapを単純に開放しても解放されない
// このため、明示的にFreeCoTaskMemを呼んでおくために一度作成したBitmapから新しくBitmapを
// 再作成し直しておくとメモリリークを抑えやすい
return new Bitmap(bitmap);
}
}
finally
{
if (intPtr != IntPtr.Zero)
Marshal.FreeCoTaskMem(intPtr);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment