我在WindowsFormsHost中有一组控件,我想捕获当前视图并将其保存为图像,但我只在图像中显示一些Panel。
是否可以将WindowsFormsHost用作“可视化”并捕获包装好的控件?
请看我的示例:
<WindowsFormsHost x:Name="windowHost">
<wf:Panel Dock="Fill" x:Name="basePanel"/>
</WindowsFormsHost>如果我要向basePanel添加一个按钮或其他什么东西,那么在使用以下代码导出到PNG时将看不到这一点:
RenderTargetBitmap rtb = new RenderTargetBitmap(basePanel.Width,
basePanel.Height, 96, 96, PixelFormats.Pbgra32);
rtb.Render(windowHost);
PngBitmapEncoder pnge = new PngBitmapEncoder();
pnge.Frames.Add(BitmapFrame.Create(rtb));
Stream stream = File.Create("test.jpg");
pnge.Save(stream);
stream.Close();关于为什么这可能不起作用的建议,以及可能的变通方法?我猜它并不是真的应该这样工作,但人们可以真的希望!
发布于 2009-11-19 00:58:32
Windows窗体控件还知道如何呈现自身,您不必跳过屏幕捕获限制。使其看起来像这样:
using (var bmp = new System.Drawing.Bitmap(basePanel.Width, basePanel.Height)) {
basePanel.DrawToBitmap(bmp, new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height));
bmp.Save(@"c:\temp\test.png");
}发布于 2009-11-18 23:54:45
WindowsFormsHost的内容是由GDI+呈现的,就像在Windows Forms应用程序中一样,因此不能使用RenderTargetBitmap,因为它不是由WPF呈现的。相反,您应该使用GDI+ BitBlt函数,该函数允许您捕获屏幕上的一个区域。
有关示例,请参阅this post
更新:以下是代码的另一个版本,更新后可与WPF一起使用:
using System.Drawing;
...
public static ImageSource Capture(IWin32Window w)
{
IntPtr hwnd = new WindowInteropHelper(w).Handle;
IntPtr hDC = GetDC(hwnd);
if (hDC != IntPtr.Zero)
{
Rectangle rect = GetWindowRectangle(hwnd);
Bitmap bmp = new Bitmap(rect.Width, rect.Height);
using (Graphics destGraphics = Graphics.FromImage(bmp))
{
BitBlt(
destGraphics.GetHdc(),
0,
0,
rect.Width,
rect.Height,
hDC,
0,
0,
TernaryRasterOperations.SRCCOPY);
}
ImageSource img = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
bmp.GetHBitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
return img;
}
return null;
}只需调用将WindowsFormsHost控件作为参数传递给Capture方法,然后对生成的ImageSource做任何您喜欢做的事情。关于BitBlt和GetDC的定义,可以看看this website (这是我写在家里的电脑上的,我现在无法访问它)
https://stackoverflow.com/questions/1756954
复制相似问题