У меня была такая же проблема раньше, я хотел скопировать содержимое UIElement
в изображение, я использовал тот же подход в ответе выше, и он, кажется, работает нормально, единственная проблема у меня есть, я хотел, чтобы она работала в режиме реального времени, поэтому мне пришлось копать глубже, я нашел несколько ссылок об использовании Windows API для копирования содержимого элемента в растровое изображение, а затем это растровое изображение необходимо преобразовать в BitmapSource
, чтобы его можно было использовать в WPF
пока все работает нормально, но похоже, что утечка памяти (не уверен насчет этого). Я попытаюсь повторно использовать UIElement
hwnd Handle и объект растрового изображения для повышения производительности и утечки памяти (если она существует)
[DllImport("gdi32.dll")]
private static extern bool BitBlt(
IntPtr hdcDest, // handle to destination DC
int nXDest, // x-coord of destination upper-left corner
int nYDest, // y-coord of destination upper-left corner
int nWidth, // width of destination rectangle
int nHeight, // height of destination rectangle
IntPtr hdcSrc, // handle to source DC
int nXSrc, // x-coordinate of source upper-left corner
int nYSrc, // y-coordinate of source upper-left corner
System.Int32 dwRop // raster operation code
);
[DllImport("User32.dll")]
public extern static System.IntPtr GetDC(System.IntPtr hWnd);
[DllImport("User32.dll")]
public extern static int ReleaseDC(System.IntPtr hWnd, System.IntPtr hDC); //modified to include hWnd
//[DllImport("gdi32.dll")]
//[return: MarshalAs(UnmanagedType.Bool)]
//internal static extern bool DeleteObject(IntPtr hObject);
private static Bitmap GetBitmapFromControl(Window element, int width, int height)
{
HwndSource hWnd = (HwndSource)HwndSource.FromVisual(element);
System.IntPtr srcDC = GetDC(hWnd.Handle);
Bitmap bm = new Bitmap(width, height);
Graphics g = Graphics.FromImage(bm);
System.IntPtr bmDC = g.GetHdc();
BitBlt(bmDC, 0, 0, bm.Width, bm.Height, srcDC, 0, 0, 0x00CC0020 /*SRCCOPY*/);
ReleaseDC(hWnd.Handle, srcDC);
g.ReleaseHdc(bmDC);
g.Dispose();
return bm;
}
public static BitmapSource ToWpfBitmap(this Bitmap bitmap)
{
using (MemoryStream stream = new MemoryStream())
{
bitmap.Save(stream, ImageFormat.Bmp);
stream.Position = 0;
BitmapImage result = new BitmapImage();
result.BeginInit();
// According to MSDN, "The default OnDemand cache option retains access to the stream until the image is needed."
// Force the bitmap to load right now so we can dispose the stream.
result.CacheOption = BitmapCacheOption.OnLoad;
result.StreamSource = stream;
result.EndInit();
result.Freeze();
//DeleteObject(bitmap.GetHbitmap());
bitmap.Dispose();
return result;
}
}