zoukankan      html  css  js  c++  java
  • 分享一个截图组件

    由于最近项目里要有一个截图功能,花了几天时间写了个小程序,封装了3个不同截屏方式,希望能给有类似需求的园友提供一点点参考

    功能概述:

    • 全屏截取
    • 区域截取
    • 窗体截取

    效果入下图示:

     

    实现方法概述

    全屏截图

            /// <summary>
            /// 获取全屏截图
            /// </summary>
            /// <returns>截图</returns>
            publicImage GetFullScreenImage()
            {
                Imageimage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
                Graphicsg = Graphics.FromImage(image);
                g.CopyFromScreen(new Point(0, 0), new Point(0, 0), Screen.PrimaryScreen.Bounds.Size);
                returnimage;
            }
    

    区域截图

    将Form设置为半透明状态,用户移动、拖拽窗体,选择区域后双击截图,Esc或鼠标右键退出。主要代码如下:

            //双击获取截图
            privatevoid GetScreenImage()
            {
                _image = new Bitmap(this.Width, this.Height);
                Graphicsg = Graphics.FromImage(_image);
                g.CopyFromScreen(this.Location, new Point(0, 0), new Size(this.Width, this.Height));
                this.DialogResult= DialogResult.OK;
            }
    

    窗体截取

    1,根据鼠标位置获取目标窗体句柄

    [DllImport("user32.dll")]
    public static extern IntPtr WindowFromPoint(Pointpoint);

    2,绘制窗体外边框,使用户知道现在要截取的窗体

    调用gdi32.dll里面的方法绘制边框,代码较多,请参见源码

    3,截图

    根据得到窗体的句柄通过如下方法获得窗体的位置和大小

     

    [DllImport("user32.dll")]
     public static extern bool GetWindowRect(IntPtrhWnd, ref RECTlpRect);
    

    被选择的窗体可能不是最前端的窗体,为了完整截取窗体,在截取之前,先把窗体通过以下方法设置为最前端窗体

       [DllImport("user32.dll")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
    

    截图方法与其他两种截图方法一样,都是用Graphics类的CopyFromScreen方法完成的

    组件使用方法

    ScreenShot类中封装了3个方法分别用于全屏截取、区域截取和窗体截取,使用方法如下:

    1,全屏截取

    _image= _screenShot.GetFullScreenImage();
    

    2,区域截取

    _image= _screenShot.GetRangeImage();
    

    3,窗体截取

    需要添加一个事件:AfterCapture,然后再调用OpenWindowImageCaptureForm方法。在事件参数里得到Image对象

    if (_screenShot.AfterCapture == null)
    {
           _screenShot.AfterCapture += new EventHandler<WindowScreenCaptureEventArgs>(ScreenShot_AfterWindowCapture);
    }
      _screenShot.OpenWindowImageCaptureForm();
    
     privatevoid ScreenShot_AfterWindowCapture(object o, WindowScreenCaptureEventArgse)
    {
             _image = e.Image;
             this.Save(_image);
    }
    

    待改进地方

    1,窗体截取时操作比较别扭,需要一个辅助窗体

          用鼠标拖拽那个园形图标到目标窗体,然后松开鼠标时,在MouseUp事件里得到目标窗体的句柄。如果没有这个MouseUp事件,我不知道在什么时候,通过什么方式来得到目标窗体的句柄。

    2,用方法SetForegroundWindow将选窗体设为最前端时不能马上奇效,权宜之计是调用完这个方法先Sleep 300ms。不然目标窗体的前的窗体也被截屏了,不知道该怎么解决。

          对Windows编程熟悉的朋友可以提些建议,谢谢。

    参考

    编写过程中,借鉴和使用了以下博客或网站的思路或代码,表示感谢。

    http://www.cnblogs.com/tuyile006/archive/2007/07/16/815843.html(全屏、区域)

    http://www.codeproject.com/KB/dialog/FindWindow.aspx(窗体截取)

    http://www.pinvoke.net/(一个很好的wiki)

    下载源码(这是csdn的地址,本来想上传到google文档的,可是google文档被和谐了,还需FQ,可惜我放在里面的文档了,哎)

    最新版本

  • 相关阅读:
    P4005 小 Y 和地铁
    P1039 侦探推理
    P2766 最长不下降子序列问题
    P2312 解方程
    P2169 正则表达式
    UOJ#22. 【UR #1】外星人
    UOJ#21. 【UR #1】缩进优化
    Palindromeness CodeChef
    bzoj5392 [Lydsy1806月赛]路径统计
    997D Cycles in product
  • 原文地址:https://www.cnblogs.com/zzy0471/p/1817971.html
Copyright © 2011-2022 走看看