C#仿QQ实现简单的截图功能

作者:Csharp小记 时间:2021-10-11 16:43:15 

接上一篇写的截取电脑屏幕,我们在原来的基础上加一个选择区域的功能,实现自定义选择截图。

个人比较懒,上一篇的代码就不重新设计了,就简单改一下呈现方式。

不得不吐槽一下,在windows10系统上设置了放大比例的话,用这种方式来实现截图功能的话需要去计算比例。后面有机会的话,用第三方DLL再实现一次。

实现功能

屏幕选择区域截图

开发环境

开发工具:Visual Studio 2013

.NET Framework版本:4.5

实现代码

//将上一篇的内容改成以下内容
// pictureBox1.Image = bmp;
Form2 frm = new Form2();
frm.BaseImage = bmp;
frm.TopMost = true;
frm.Show();

/*Form2代码*/
#region Dll引用
[DllImport("User32.dll", EntryPoint = "GetDC")]
private extern static IntPtr GetDC(IntPtr hWnd);

[DllImport("User32.dll", EntryPoint = "ReleaseDC")]
private extern static int ReleaseDC(IntPtr hWnd, IntPtr hDC);

[DllImport("gdi32.dll")]
public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);

[DllImport("User32.dll")]
public static extern int GetSystemMetrics(int hWnd);

const int DESKTOPVERTRES = 117;
const int DESKTOPHORZRES = 118;

const int SM_CXSCREEN = 0;
const int SM_CYSCREEN = 1;

#endregion

//<summary>
//获取DPI缩放比例
//</summary>
//<param name="dpiscalex"></param>
//<param name="dpiscaley"></param>
public static void GetDPIScale(ref float dpiscalex, ref float dpiscaley)
{
   int x = GetSystemMetrics(SM_CXSCREEN);
   int y = GetSystemMetrics(SM_CYSCREEN);
   IntPtr hdc = GetDC(IntPtr.Zero);
   int w = GetDeviceCaps(hdc, DESKTOPHORZRES);
   int h = GetDeviceCaps(hdc, DESKTOPVERTRES);
   ReleaseDC(IntPtr.Zero, hdc);
   dpiscalex = (float)w / x;
   dpiscaley = (float)h / y;
}

public Bitmap BaseImage { get; set; }

Graphics picGraphics;
//记录鼠标开始截图的位置
int startX = 0, startY = 0;
//记录鼠标结束截图的位置
int endX = 0, endY = 0;
//记录DPI缩放比例
float x = 0f, y = 0f;
public Form2()
{
   InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
   /* 初始化赋值*/

GetDPIScale(ref x, ref y);
   picGraphics = pictureBox1.CreateGraphics();
}

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
   DrawRect(endX - startX, endY - startY,e.Graphics);
}

private void Form2_KeyPress(object sender, KeyPressEventArgs e)
{
   //按下esc退出
   if (e.KeyChar == 27)
   {
       this.Close();
   }
}

//完成截图
private void lbSucess_Click(object sender, EventArgs e)
{
   int clip_w = (int)((endX - startX) * x) - 4, clip_h = (int)((endY - startY) * y) - 4;
   if (clip_w < 1 || clip_h < 1)
   {
       return;
   }
   //获取截图
   Bitmap clipBmp = new Bitmap(clip_w, clip_h);
   Graphics g = Graphics.FromImage(clipBmp);
   g.CopyFromScreen((int)(startX * x) + 2, (int)(startY * y) + 2, 0, 0, new Size(clip_w, clip_h), CopyPixelOperation.SourceCopy);
   //将截图设置到剪切板
   Clipboard.SetImage(clipBmp);
   g.Dispose();
   this.Close();
}

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
   //隐藏操作面板
   panel1.Visible = false;
   //记录鼠标开始截图的位置
   if (e.Button == MouseButtons.Left)
   {
       startX = e.X;
       startY = e.Y;
       endX = 0; endY = 0;
   }
}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
   if (e.Button == MouseButtons.Left)
   {
       //绘制截图区域
       DrawRect(e.X - startX, e.Y - startY, picGraphics);
   }
}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
   //截图完成
   if (e.Button == MouseButtons.Left)
   {
       endX = e.X;
       endY = e.Y;

DrawRect(endX - startX, endY - startY, picGraphics);
       if (endX > startX && endY > startY)
       {
           //显示操作面板
           Thread.Sleep(100);
           panel1.Location = new Point(e.X - panel1.Width, e.Y + 5);
           panel1.Visible = true;

}
   }
}

//绘制截图区域
private void DrawRect(int w, int h,Graphics g)
{
   Bitmap img = (Bitmap)BaseImage.Clone();

//双缓冲技术画矩形,防止重影和抖动
   Graphics Painter = Graphics.FromImage(img);
   Painter.DrawRectangle(new Pen(Color.Red), startX * x, startY * y, w * x, h * y);
   g.DrawImage(img, 0, 0, img.Width / x, img.Height / y);

Painter.Dispose();
   img.Dispose();
}

实现效果

C#仿QQ实现简单的截图功能

我这边演示代码很少做异常处理(前面也是,后面也是,毕竟不是做项目为主),大家使用的时候根据情况自行处理下即可,亦或者可能会有内存未及时释放的情况。

来源:https://mp.weixin.qq.com/s/770Y-qNKkLW_z0fDEupOMw

标签:C#,截图
0
投稿

猜你喜欢

  • Android中ListView下拉刷新的实现方法实例分析

    2023-07-31 01:40:27
  • 详谈Java中net.sf.json包关于JSON与对象互转的坑

    2023-03-02 12:38:31
  • Java单元测试工具之JUnit的使用

    2022-09-05 13:20:54
  • 浅谈java多态的实现主要体现在哪些方面

    2023-08-17 07:41:32
  • 详解SpringMVC常用注解功能及属性

    2021-12-29 02:49:23
  • Java 8新特性方法引用详细介绍

    2023-06-22 08:31:50
  • java compare compareTo方法区别详解

    2022-06-26 08:13:55
  • java设计模式之工厂方法详解

    2023-09-09 01:18:56
  • Java中JFrame实现无边框无标题方法

    2021-11-25 20:35:54
  • springboot应用访问zookeeper的流程

    2021-11-28 00:34:56
  • Java下SpringBoot创建定时任务详解

    2023-10-03 01:25:23
  • C#中的高阶函数介绍

    2022-12-05 02:41:46
  • SpringMVC框架实现图片上传与下载

    2022-01-12 23:50:52
  • Java实现高校教务系统

    2022-05-16 04:24:17
  • C#窗体间通讯的几种常用处理方法总结

    2021-10-26 05:48:49
  • java导出Excel通用方法的实例详解

    2022-06-25 14:28:25
  • C#实现HTTP上传文件的方法

    2023-04-28 04:05:30
  • 详解Spring Boot最核心的27个注解,你了解多少?

    2023-11-20 06:23:35
  • java自动生成ID号的方法

    2023-11-18 11:17:56
  • Maven管理SpringBoot Profile详解

    2022-03-20 09:57:45
  • asp之家 软件编程 m.aspxhome.com