下面的代码对屏幕的一部分进行快照(在鼠标坐标处),并将其显示在Image控件中。
public partial class MainWindow : Window
{
Timer timer = new Timer(100);
public MainWindow()
{
InitializeComponent();
timer.Elapsed += Timer_Elapsed;
timer.Start();
}
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
viewerImage.Source = GetSnapAtMouseCoords((int)((Grid)viewerImage.Parent).ActualWidth, (int)((Grid)viewerImage.Parent).ActualHeight, System.Windows.Forms.Cursor.Position);
}
private BitmapSource GetSnapAtMouseCoords(int width, int height, System.Drawing.Point mousePosition)
{
IntPtr handle = IntPtr.Zero;
try
{
using (var screenBmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
{
using (var bmpGraphics = Graphics.FromImage(screenBmp))
{
bmpGraphics.CopyFromScreen(mousePosition.X, mousePosition.Y, 0, 0, screenBmp.Size);
handle = screenBmp.GetHbitmap();
var bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
handle,
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
return bs;
}
}
}
finally
{
DeleteObject(handle);
}
}
}
一切正常,直到将图像源设置为BitmapSource为止。不幸的是,该图像从未在屏幕上呈现。
我认为这可能是因为我正在GUI线程上创建BitmapSource ...但是我不确定。
欢迎任何建议或想法。
实际上,这是因为您正在不同的线程上访问GUI。您可以像这样包装初始调用:
Dispatcher.BeginInvoke(new Action(() =>
{
viewerImage.Source = GetSnapAtMouseCoords(
(int)((Grid)viewerImage.Parent).ActualWidth,
(int)((Grid)viewerImage.Parent).ActualHeight,
System.Windows.Forms.Cursor.Position);
}));
或在后台线程中执行所有处理,只需返回Frozen
(Thread safe)即可BitmapSource
。您将需要悬停传递(int)((Grid)viewerImage.Parent).ActualWidth
不同的内容,因为它也归UI线程所有。
bs.Freeze();
Dispatcher.BeginInvoke(new Action(() =>
{
viewerImage.Source = bs;
}));
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句