桌面C#(WPF)截图时延迟

桌面C#(WPF)截图时延迟,c#,wpf,screenshot,gdi,C#,Wpf,Screenshot,Gdi,我正在做一些截图程序。它的功能与Windows的剪贴工具相同。用户通过在屏幕上绘制矩形来定义区域,并进行拍摄 我遵循这一惊人的做法,比如打开新窗口,覆盖整个桌面。然后我在窗口上画一个长方形,在长方形内拍照。如果鼠标正常移动,则屏幕截图拍摄正确。喜欢这个图像吗 但是,当鼠标移动得更快时,屏幕截图拍摄错误,如下图所示。快照从矩形区域中取出 以下是源代码: public partial class CapturingArea : Window { public BitmapSource

我正在做一些截图程序。它的功能与Windows的剪贴工具相同。用户通过在屏幕上绘制矩形来定义区域,并进行拍摄

我遵循这一惊人的做法,比如打开新窗口,覆盖整个桌面。然后我在窗口上画一个长方形,在长方形内拍照。如果鼠标正常移动,则屏幕截图拍摄正确。喜欢这个图像吗

但是,当鼠标移动得更快时,屏幕截图拍摄错误,如下图所示。快照从矩形区域中取出

以下是源代码:

public partial class CapturingArea : Window
{

    public  BitmapSource    mTakenScreenShot;
    private Point           mStartPoint;
    private Point           mEndPoint;                
    private Rectangle       mDrawRectangle;       

    public CapturingArea()
    {
        InitializeComponent();
        InitMainWindow();            
        Mouse.OverrideCursor = Cursors.Cross;

        mStartPoint = new Point();
        mEndPoint   = new Point();            
    }      

    /*Close Window by pressing ESC Button*/
    private void Window_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Escape)
        {
            Mouse.OverrideCursor = Cursors.Arrow;
            this.Close();                
        }
    }        

    /*When Mouse is clicked 
     get the current point of Mouse and Start Drawing Rectangle on the Canvas*/
    private void cnDrawingArea_MouseDown(object sender, MouseButtonEventArgs e)
    {            
        if(mDrawRectangle != null)
            this.cnDrawingArea.Children.Remove(mDrawRectangle);

        mStartPoint = e.GetPosition(this);                  

        mDrawRectangle = new Rectangle
        {
            Stroke = Brushes.Red,
            StrokeThickness = 0.5
        };

        Canvas.SetLeft(mDrawRectangle, mStartPoint.X);
        Canvas.SetTop(mDrawRectangle, mStartPoint.Y);
        this.cnDrawingArea.Children.Add(mDrawRectangle);
    }

    /* Continue drawing Rectangle while Mouse is moving on the Canvas Area*/
    private void cnDrawingArea_MouseMove(object sender, MouseEventArgs e)
    {
        if(e.LeftButton == MouseButtonState.Released)
        {
            return;
        }

        Point tmpPoint = e.GetPosition(this.cnDrawingArea);

        int xPos = (int) Math.Min(tmpPoint.X, mStartPoint.X);
        int yPos = (int) Math.Min(tmpPoint.Y, mStartPoint.Y);

        int recWidth = (int) Math.Max(tmpPoint.X, mStartPoint.X) - xPos;
        int recHeight = (int)Math.Max(tmpPoint.Y, mStartPoint.Y) - yPos;

        mDrawRectangle.Width = recWidth;
        mDrawRectangle.Height = recHeight;
        Canvas.SetLeft(mDrawRectangle, xPos);
        Canvas.SetTop(mDrawRectangle, yPos);
    }
    /*Initialize Window to cover whole screen*/
    private void InitMainWindow()
    {
        this.WindowStyle = WindowStyle.None;
        this.Title = string.Empty;
        this.ShowInTaskbar = false;
        this.AllowsTransparency = true;
        this.Background = new SolidColorBrush(Color.FromArgb(0x10, 0x10, 0x10, 0x10));
     //   this.Topmost = true;
        this.Left   = SystemParameters.VirtualScreenLeft;
        this.Top    = SystemParameters.VirtualScreenTop;
        this.Width  = SystemParameters.VirtualScreenWidth;
        this.Height = SystemParameters.VirtualScreenHeight;
    }


    /*First calculate Starting Ending points according to 
     mouse move and take screenshot*/
    private void CaptureScreen(int X1, int Y1, int X2, int Y2)
    {
        int StartXPosition = 0;
        int StartYPosition = 0;
        int tmpWidth = 0;
        int tmpHeight = 0;

        if (X1 < X2 && Y1 < Y2)          /*Drawing Left to Right*/
        {
            StartXPosition = X1;
            StartYPosition = Y1;
            tmpWidth  = X2 - X1;
            tmpHeight = Y2 - Y1;
        } 
        else if(X1 > X2 && Y1 < Y2)     /*Drawing Top to Down*/
        {
            StartXPosition = X2;
            StartYPosition = Y1;
            tmpWidth  = X1 - X2;
            tmpHeight = Y2 - Y1;
        } 
        else if(X1 > X2 && Y1 > Y2)     /*Drawing Down to Top*/
        {
            StartXPosition = X2;
            StartYPosition = Y2;
            tmpWidth = X1 - X2;
            tmpHeight = Y1 - Y2;
        } 
        else if(X1 < X2 && Y1 >Y2)      /*Drawing Right to Left */
        {
            StartXPosition = X1;
            StartYPosition = Y2;
            tmpWidth  = X2 - X1;
            tmpHeight = Y1 - Y2;
        }
        StartXPosition += 2;
        StartYPosition += 2;
        tmpWidth -= 2;
        tmpHeight -= 2;
        mTakenScreenShot = ScreenCapture.CaptureRegion(StartXPosition, StartYPosition, tmpWidth, tmpHeight, false);
        Mouse.OverrideCursor = Cursors.Arrow;
    }

    /*get the screenshot and by calculating real positions of Desktop*/
    private void cnDrawingArea_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {            
            if (e.LeftButton == MouseButtonState.Released)
            {
                mEndPoint = e.GetPosition(this.cnDrawingArea);

                if (mDrawRectangle != null)
                    this.cnDrawingArea.Children.Remove(mDrawRectangle);

                Point StartDesktopPosition = this.PointToScreen(mStartPoint);   
                Point EndDesktopPosition = this.PointToScreen(mEndPoint);

                int tempX1 = (int)StartDesktopPosition.X;
                int tempY1 = (int)StartDesktopPosition.Y;
                int tempX2 = (int)EndDesktopPosition.X;
                int tempY2 = (int)EndDesktopPosition.Y;

                CaptureScreen(tempX1, tempY1, tempX2, tempY2);
                this.DialogResult = true;
                this.Close();
            }
        }
    }
公共部分类CapturingArea:窗口
{
公共位图源屏幕截图;
私人点mStartPoint;
私人点;
私有矩形;
公共CapturingArea()
{
初始化组件();
InitMainWindow();
Mouse.OverrideCursor=游标.Cross;
mStartPoint=新点();
mEndPoint=新点();
}      
/*按ESC按钮关闭窗口*/
私有无效窗口\u KeyUp(对象发送方,KeyEventArgs e)
{
if(e.Key==Key.Escape)
{
Mouse.OverrideCursor=Cursors.Arrow;
这个。关闭();
}
}        
/*单击鼠标时
获取鼠标的当前点并开始在画布上绘制矩形*/
私有void cnDrawingArea_MouseDown(对象发送器,鼠标按钮ventargs e)
{            
if(mDrawRectangle!=null)
此.cnDrawingArea.Children.Remove(mDrawRectangle)为.cnDrawingArea.Children.Remove;
mStartPoint=e.GetPosition(此);
mDrawRectangle=新矩形
{
笔划=画笔。红色,
冲程厚度=0.5
};
SetLeft(mDrawRectangle,mStartPoint.X);
SetTop(mDrawRectangle,mStartPoint.Y);
this.cnDrawingArea.Children.Add(mDrawRectangle);
}
/*当鼠标在画布区域上移动时,继续绘制矩形*/
私有void cnDrawingArea_MouseMove(对象发送方,MouseEventArgs e)
{
如果(e.LeftButton==鼠标按钮状态.已释放)
{
返回;
}
点tmpPoint=e.GetPosition(此.cnDrawingArea);
intxpos=(int)Math.Min(tmpPoint.X,mStartPoint.X);
intypos=(int)Math.Min(tmpPoint.Y,mStartPoint.Y);
int recWidth=(int)Math.Max(tmpPoint.X,mStartPoint.X)-xPos;
int recHeight=(int)Math.Max(tmpPoint.Y,mStartPoint.Y)-yPos;
mDrawRectangle.Width=recWidth;
mDrawRectangle.Height=recHeight;
SetLeft(mDrawRectangle,xPos);
SetTop(mDrawRectangle,yPos);
}
/*初始化窗口以覆盖整个屏幕*/
私有void InitMainWindow()
{
this.WindowStyle=WindowStyle.None;
this.Title=string.Empty;
this.ShowInTaskbar=false;
this.allowsttransparency=true;
this.Background=新的SolidColorBrush(Color.FromArgb(0x10,0x10,0x10,0x10));
//这个.Topmost=true;
this.Left=SystemParameters.VirtualScreenLeft;
this.Top=SystemParameters.VirtualScreenTop;
this.Width=SystemParameters.VirtualScreenWidth;
this.Height=SystemParameters.VirtualScreenHeight;
}
/*首先根据以下公式计算起点和终点:
鼠标移动并截图*/
专用无效捕获屏幕(int X1、int Y1、int X2、int Y2)
{
int StartXPosition=0;
int StartYPosition=0;
int tmpWidth=0;
int tmpHeight=0;
如果(X1X2&&Y1X2&&Y1>Y2)/*向下绘制到顶部*/
{
起始位置=X2;
星型定位=Y2;
tmpWidth=X1-X2;
tmpHeight=Y1-Y2;
} 
如果(X1Y2)/*从右向左绘制*/
{
StartXPosition=X1;
星型定位=Y2;
tmpWidth=X2-X1;
tmpHeight=Y1-Y2;
}
起始位置+=2;
星型定位+=2;
tmpWidth-=2;
tmpHeight-=2;
mTakenScreenShot=ScreenCapture.CaptureRegion(起始位置、起始位置、tmpWidth、tmpHeight、false);
Mouse.OverrideCursor=Cursors.Arrow;
}
/*通过计算桌面的实际位置,获取屏幕截图和*/
私有无效cnDrawingArea_MouseLeftButtonUp(对象发送器,MouseButtonEventArgs e)
{            
如果(e.LeftButton==鼠标按钮状态.已释放)
{
mEndPoint=e.GetPosition(此.cnDrawingArea);
if(mDrawRectangle!=null)
此.cnDrawingArea.Children.Remove(mDrawRectangle)为.cnDrawingArea.Children.Remove;
Point StartDesktopPosition=此.PointToScreen(mStartPoint);
Point EndDesktopPosition=此点到屏幕(mEndPoint);
int tempX1=(int)StartDesktopPosition.X;
int tempY1=(int)StartDesktopPosition.Y;
int tempX2=(int)EndDesktopPosition.X;
int tempY2=(int)EndDesktopPosition.Y;
捕获屏幕(tempX1、tempY1、tempX2、tempY2);
this.DialogResult=true;
这个。关闭();
}
}
}
当鼠标快速移动以拍摄正确的屏幕截图时,是否有任何解决方案或建议


谢谢。

当鼠标快速移动时,窗口将聚合