C#实现对任意区域任意大小的截图

1,目的:

  • 实现类似系统截图工具那样对屏幕任何区域自定义大小的截图。

2,效果展示:

  • 点击截图

  • 选择需要截图的区域:

  • 区域选择完成后,单击右键完成截图:

  • 在合适的载体上粘贴截图:

3,代码:

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
            //获取屏幕截屏
            Bitmap bcgImg = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
            using (Graphics g= Graphics.FromImage(bcgImg))
            {
                g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(bcgImg.Width, bcgImg.Height));

            }
            //将图片传给截图窗口
            CaptureFrm frm = new CaptureFrm(bcgImg);
            frm.TopMost = true;
           if( frm.ShowDialog()== DialogResult.OK)
            {
                MessageBox.Show("截图已保存至剪贴板,请选择合适的载体进行粘贴!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("取消截图","提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            this.WindowState = FormWindowState.Normal;
        }
    }
public partial class CaptureFrm : Form
    {
        Bitmap bcgImg;
        bool drawingFlag=false;
        Point startPoint;
        Point endPoint;
        Graphics main_g;
        bool isCapture=false;
        public CaptureFrm(Bitmap img)
        {
            InitializeComponent();
            bcgImg = img;
        }

        private void CaptureFrm_Load(object sender, EventArgs e)
        {
            //背景
            this.BackgroundImage = bcgImg;
            this.BackgroundImageLayout = ImageLayout.Stretch;

        }

        private void CaptureFrm_KeyDown(object sender, KeyEventArgs e)
        {
            //如果按下ESC键则退出
            if (e.KeyCode == Keys.Escape)
            {
                //  this.Close();
                DialogResult = DialogResult.Cancel;
            }
        }

        private void CaptureFrm_MouseDown(object sender, MouseEventArgs e)
        {
          if(e.Button== MouseButtons.Left)
            {
                drawingFlag = true;
                startPoint = e.Location;
                main_g = this.CreateGraphics();
            }
          if(e.Button== MouseButtons.Right)
            {
                if (isCapture)
                {
                    Bitmap map = new Bitmap(width, height);
                    Bitmap source = new Bitmap(bcgImg, new Size(this.Width, this.Height));
                    using (Graphics g = Graphics.FromImage(map))
                    {
                        g.DrawImage(source, new Rectangle(0, 0, map.Width, map.Height), new Rectangle(recX, recY, width, height), GraphicsUnit.Pixel);
                    }
                    Clipboard.SetImage(map);
                    main_g.Dispose();
                    DialogResult = DialogResult.OK;
                    isCapture = false;
                }
            }
            
            
        }

        private void CaptureFrm_MouseUp(object sender, MouseEventArgs e)
        {
            if(e.Button== MouseButtons.Left)
            {
                //进行最终边界确认
                endPoint = e.Location;
                drawingFlag = false;
                isCapture = true;
            }
           
        }
        int recX, recY, width, height;
        private void CaptureFrm_MouseMove(object sender, MouseEventArgs e)
        {
            if (!drawingFlag ||main_g==null) return;
            
            width = Math.Abs(startPoint.X - e.X);
            height = Math.Abs(startPoint.Y - e.Y);
            if (startPoint.X < e.X)
            {
                recX = startPoint.X;
            }
            else
            {
                recX = startPoint.X-width;
            }
            if (startPoint.Y < e.Y)
            {
                recY = startPoint.Y;
            }
            else
            {
                recY = startPoint.Y-height;
            }
            CaptureFrm_Paint(null, null);
            Pen pen = new Pen(Color.Green, 2);
            pen.DashPattern = new float[] { 1, 2 };
            pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
            main_g.DrawRectangle(pen, recX, recY, width, height);
            string ss = $"X:{recX},Y:{recY}\n width:{width},height:{height}";
            main_g.DrawString(ss, new Font("宋体", 12,FontStyle.Bold), Brushes.Red, new Point(10, 10));
        }

        private void CaptureFrm_Paint(object sender, PaintEventArgs e)
        {
            if (main_g == null) return;
          //  main_g.Clear(Color.WhiteSmoke);
            main_g.DrawImage(bcgImg, new Rectangle(0, 0, this.Width, this.Height), new Rectangle(0, 0, bcgImg.Width, bcgImg.Height), GraphicsUnit.Pixel);
           
        }

        private void CaptureFrm_DoubleClick(object sender, EventArgs e)
        {
           
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/354550.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

周期性信号展开成傅里叶级数【可视化】

傅里叶变换的本质&#xff1a;叠加性&#xff0c;每个圆代表一个谐波分量 先详细解释下这个图 看图时&#xff0c;先确定 X X X 轴的点位&#xff0c;再垂直 Y Y Y、 Z Z Z轴找到对应的波形&#xff0c;如 x 0 x0 x0 时&#xff0c;找到了一个橙色的直线 X X X 轴 - 频率…

代码随想录算法训练营第32天 | 122.买卖股票的最佳时机II 55.跳跃游戏 45.跳跃游戏II

买卖股票的最佳时机II 贪心思路 要想使用贪心算法解决此问题&#xff0c;意识到利润是可分解的很关键。比如[1,2,3,4,5]这个输入&#xff0c;最大利润为第一天买入&#xff0c;第五天卖出。这等效于第一天买入&#xff0c;第二天卖出&#xff0c;第二天再买入。。。 prices[4]…

用navigator.sendBeacon完成网页埋点异步请求记录用户行为,当网页关闭的时候,依然后完美完成接口请求,不会因为浏览器关闭了被中断请求。

代码用例 <template><div :class"$options.name"><el-button type"primary" click"sendBeacon">navigator.sendBeacon 请求埋点接口 发送json对象数据</el-button></div> </template><script> expor…

WindowsOS

C:. ├─PerfLogs&#xff0c;系统日志文件夹 ├─Program Files&#xff0c;程序文件 ├─Program Files&#xff08;x86&#xff09;&#xff0c;程序文件&#xff08;x86&#xff09; ├─ProgramData&#xff0c;程序数据 ├─Windows&#xff0c;Windows系统文件夹 └─Us…

从零开始做题:逆向 ret2libc warmup

1.题目信息 warmup.c //gcc -fno-stack-protector -no-pie -z execstack warmup.c -o warmup #include <stdio.h>void init_proc(){setbuf(stdout, NULL);setbuf(stdin, NULL);setbuf(stderr, NULL); }int main(void) {char buf[0x100];init_proc();puts("Hello C…

python解决n以内的质数问题

对于日常的一些问题,例如求出n以内的质数问题,这都是经常会遇到的一些问题,可能会在面试的过程当中都会被问到的问题,所以针对这个比较基础的问题进行解答。 问题是需要找出n以内的所有质数(不包括n这个数),质数的定义是在大于1的自然数中,除了1和它本身以外,不再有其…

Go 为什么建议使用切片,少使用数组?

1 介绍 在 Go 语言中&#xff0c;数组固定长度&#xff0c;切片可变长度&#xff1b;数组和切片都是值传递&#xff0c;因为切片传递的是指针&#xff0c;所以切片也被称为“引用传递”。 读者朋友们在使用 Go 语言开发项目时&#xff0c;或者在阅读 Go 开源项目源码时&#…

ctfhub—RCE通关

0、前言 0.1 、什么是RCE RCE全称&#xff1a;Remote Command/Code Execute&#xff0c;远程命令执行或者代码执行。RCE漏洞&#xff0c;可以让攻击者直接向后台服务器远程注入操作系统命令或者代码&#xff0c;从而控制后台系统。 为什么会有命令执行漏洞呢&#xff1f;因为…

使用电脑时突然遇到“mfc140.dll文件丢失”的问题都有什么解决办法

当你在使用电脑时突然遇到“mfc140.dll文件丢失”的问题时&#xff0c;可能会感到困惑和苦恼。一旦出现这样的问题&#xff0c;缺少这个文件可能导致一些应用程序无法正常启动&#xff0c;影响你的工作和娱乐体验。其实这个问题是可以解决的&#xff0c;接下来我们将介绍一些可…

xxl-job相关面试题整理

什么是xxl-job&#xff1f; ​ xxl-job是一个分布式的任务调度平台&#xff0c;其核心设计目标是&#xff1a;学习简单、开发迅速、轻量级、易扩展&#xff0c;现在已经开放源代码并接入多家公司的线上产品线&#xff0c;开箱即用。xxl是xxl-job的开发者大众点评的许雪里名称的…

CSS3基础知识总结

目录 一、CSS3 边框 1.border-radius&#xff1a;圆角边框 2.box-shadow&#xff1a;添加阴影 3.border-image&#xff1a;图片边框 二、CSS3 渐变 1.线性渐变(Linear Gradients) a.由上到下&#xff08;默认&#xff09; b.从左到右 c.对角 d.使用角度 2.径向渐变(…

计算机提示缺失dll文件怎么办?那种dll解决方法更值得推荐

当在运行游戏&#xff0c;软件程序的过程中遇到“找不到dll”的情况时&#xff0c;这实际上意味着系统或应用程序无法定位并加载必要的动态链接库文件&#xff08;DLL&#xff09;&#xff0c;从而无法顺利完成预期的功能调用和执行流程。这种问题的发生可能会引发一系列严重后…

蓝桥云课-第4场小白赛理解

网址&#xff1a;第 4 场 小白入门赛 - 蓝桥云课 (lanqiao.cn) 第一题&#xff1a;美丽的2024 思路&#xff1a; 2024 -直接用变成二进制的函数或者模拟二进制的过程&#xff0c;找到有几个1就行 第二题&#xff1a;自助餐 题目&#xff1a; 思路&#xff1a;就是用字符串代…

x-cmd pkg | go - Google 开发的开源编程语言

目录 简介首次用户技术特点竞品分析编译型语言解释型语言JavaWebAssebmly 进一步阅读 简介 Go 语言&#xff08;或 Golang&#xff09;是 Google 开发的开源编程语言&#xff0c;诞生于 2006 年。其设计目标是“兼具 Python 等动态语言的开发速度和 C/C 等编译型语言的性能与安…

设计模式:工厂方法模式

工厂模式属于创建型模式&#xff0c;也被称为多态工厂模式&#xff0c;它在创建对象时提供了一种封装机制&#xff0c;将实际创建对象的代码与使用代码分离&#xff0c;有子类决定要实例化的产品是哪一个&#xff0c;把产品的实例化推迟到子类。 使用场景 重复代码 : 创建对象…

一文读懂mysql的锁

提起mysql的锁&#xff0c;你是否会似懂非懂&#xff0c;最常听人提起的就是乐观锁&#xff0c;悲观锁、排他锁、共享锁 悲观锁是用 select c form T for update然后等待提交实现的&#xff0c;但是你知道吗&#xff0c;其实排他锁和悲观锁其实是一回事&#xff01;&#xff0…

redis-4 搭建redis集群

1.为什么需要redis集群&#xff1f; Redis 集群提供了高可用性、横向扩展和数据分片等功能&#xff0c;使得 Redis 能够应对大规模的数据存储和高并发访问的需求。以下是一些需要使用 Redis 集群的常见情况&#xff1a; 高可用性&#xff1a;通过在多个节点之间进行数据复制和…

假期刷题打卡--Day17

1、MT1163孪生质数 在质数中&#xff0c;若两个质数之差为2,我们称之为孪生质数,例如&#xff08;3、5&#xff09;&#xff08;5、7&#xff09;&#xff0c;输入2个正整数&#xff0c;判断他是不是孪生质数&#xff0c;输出YES或者NO。 格式 输入格式&#xff1a; 输入整…

求职就业,你需要了解人才测评的应用流程

很多求职者心中都有一个困惑&#xff0c;不知道该人才测评的流程是如何进行&#xff0c;只知道完成基本的测试&#xff0c;完全不明白测试过程如何进行。但实际上&#xff0c;这个过程十分简单&#xff0c;并不像传说中那样神秘&#xff0c;很多人都能够弄懂过程的原理。一旦熟…

一文搞懂如何开通miniQMT(全网最清晰版本)

前言 本篇文章&#xff0c;目的是说清楚如何开通miniQMT&#xff0c;给出最清晰的开通路径。关于miniQMT是什么&#xff0c;可以参考我之前的文章《什么是miniQMT?》 1、开通券商版QMT 首先&#xff0c;迅投的QMT软件&#xff0c;与大部分券商都存在深度合作。也就是说&…