C#实现QQ截图功能及相关问题

2019-12-30 18:17:23丽君

对于QQ截图,肯定是早就有认识了,只是一直没有去认真观察这个操作的具体实现步骤。所以这里将自己的记忆中的步骤简单的写一下:

习惯性用QQ或者TIM的人,一般是使用Ctrl+Alt+A  快捷键(热键)快速实现截图。

Ctrl+Alt+A  进入截图模式 鼠标左键点击 鼠标拖动对截图去进行选取 鼠标左键弹起 双击截图区域  保存图片到剪贴板 鼠标右键点击 退出截图模式

C#,QQ截图,截图

因为考虑到截图模式的时候  一般只能显示一个窗体  所以就考虑使用单例模式  在ScreenBody窗体中实现以下代码

1:创建单例 


private static ScreenBody screenBody=null;

2:私有化构造函数


private ScreenBody()
{
InitializeComponent();
}

3:创建静态方法


private static ScreenBody GetSingle()
{
if(screenBody==null)
{
screenBody=new ScreenBody();
}
return screenBody;
}

进一步讨论一下在Main窗体中的调用  Main中添加了一个button 命名为btnCutter 


private void btnCutter_Click(object sender,EventArgs e)
{
 //新建一个和屏幕大小相同的图片img 也可以用BitMap
image img=new Bitmap(Screen.AllScreens[0].Bounds.Width,Screen.AllScreens[0].Bounds.Height);
//创建一个画板 让我们可以在画板上画图 大小和屏幕大小一样大
Graphics g=Graphics.FromImage(img);
 //将屏幕图片拷贝到空白图片img
g.CopyFromScreen(new Point(0,0),new Point(0,0),Screen.AllScreens[0].Bounds.Size);
//创建截图窗体
ScreenBody body=ScreenBody.GetSingle();
//指示窗体的背景图片为屏幕图片
body.BackGroundImage=img;
body.ShowDialog();

}

对于窗体ScreenBody

声明全局变量


private bool CatchStart;//判断鼠标是否按下
private bool CatchFinished;//判断矩形是否绘制完成
private Point DownPoint;//鼠标按下的点
private Image baseMap;//最基本的图片
private Rectangle CatchRectangle;  

必须要实现的那几个事件

鼠标按下MouseDown


 private void ScreenBody_MouseDown(object sender, MouseEventArgs e)
  {
   //鼠标左键按下就是开始画图,也就是截图
   if (e.Button == MouseButtons.Left)
   {
    if (CatchStart == false)
    {
     CatchStart = true;
     //保存此时的坐标
     DownPoint = new Point(e.X, e.Y);
    }
   }
  }

鼠标移动 MouseMove


 private void ScreenBody_MouseMove(object sender, MouseEventArgs e)
  {
   //确保截图开始
   if (CatchStart)
   {
    //新建一个图片,让它与屏幕图片相同
    Bitmap copyBmp = (Bitmap)baseMap.Clone();
    //鼠标按下时的坐标
    Point newPoint = new Point(DownPoint.X, DownPoint.Y);

    //新建画板和画笔
    Graphics g = Graphics.FromImage(copyBmp);
    Pen p = new Pen(Color.Azure, 1);//画笔的颜色为azure 宽度为1

    //获取矩形的长度 
    int width = Math.Abs(e.X - DownPoint.Y);
    int height = Math.Abs(e.Y - DownPoint.Y);

    if (e.X < DownPoint.X)
    {
     newPoint.X = e.X;

    }
    if (e.Y < DownPoint.Y)
    {
     newPoint.Y = e.Y;
    }

    CatchRectangle = new Rectangle(newPoint, new Size(width, height));
    g.DrawRectangle(p, CatchRectangle);

    //释放目前的画板
    g.Dispose();
    p.Dispose();

    //从当前窗体创建新的画板
    Graphics g1 = this.CreateGraphics();
    //将刚刚所画的图片画到截图窗体上去
    //为什么不直接在当前窗体画图呢???
    //如果直接解决将矩形画在窗体上,会造成图片抖动而且有多个矩形
    //这样实现也属于二次缓冲技术
    g1.DrawImage(copyBmp, new Point(0, 0));
    g1.Dispose();

    //释放拷贝图片 防止内存被大量的消耗
    copyBmp.Dispose();
   }