C#winfrom端屏幕截图功能的简单实现(修改了屏幕的缩放比例后,截图功能异常,慎用!!!)

文章目录

  • 1 主要文件
    • 1.1 FrmScreenShot.cs
    • 1.2 FrmScreenShot.Designer.cs
    • 1.1 Utility.cs

在发现有一款播放软件禁止截图功能后,使用了其他的截图工具发现都会被播放软件禁用掉截图功能,想了下试着自己做一个截图工具,也可以方便将截图工具添加在以后的项目中,是制作过程中也考虑到了一台电脑包含多个显示器的情况。

注意:最后发现在修改了屏幕的缩放比例后截图效果异常,由于时间不允许后续有时间再作更新。。

截图效果展示
在这里插入图片描述

1 主要文件

屏幕截图中主要文件包含
FrmScreenShot.cs
FrmScreenShot.Designer.cs
Utility.cs

1.1 FrmScreenShot.cs

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace ScreenShot
{
    /// <summary>
    /// 截取到屏幕的图像
    /// </summary>
    public partial class FrmScreenShot : Form
    {

        /// <summary>
        /// 打开截图
        /// </summary>
        public static void OpenShotScreen()
        {
            try
            {
                new FrmScreenShot().Show();
            }
            catch (Exception ex)
            {
                
            }
        }

        private readonly EBoundType[] _AllBoundType =
        {
            EBoundType.Updata_1,
            EBoundType.Updata_2,
            EBoundType.Updata_3,
            EBoundType.Updata_4,
            EBoundType.Updata_5,
            EBoundType.Updata_6,
            EBoundType.Updata_7,
            EBoundType.Updata_8,
            EBoundType.Updata_9,
        };
        private Bitmap _bmp;

        /// <summary>
        /// 鼠标按下、抬起(移动时的位置)
        /// </summary>
        private Point _mouseDownLocation, _mouseUpLocation;

        /// <summary>
        /// 当前选择边角类型
        /// </summary>
        public EBoundType _boundType = EBoundType.Wait;

        /// <summary>
        /// 图像绘制区域
        /// </summary>
        private Rectangle _bitmapDrawRect;

        /// <summary>
        /// 选择的区域(获取到鼠标在屏幕的坐标)
        /// </summary>
        private Rectangle _selectRect, _selectRectLast;

        /// <summary>
        /// 选择区域的边角区域尺寸
        /// </summary>
        private Size _boundAreaWidth = new Size(6, 6);

        public FrmScreenShot()
        {
            InitializeComponent();

            StartPosition = FormStartPosition.WindowsDefaultLocation;

            _bmp = Utility.CopyScreenToImage(out _bitmapDrawRect);
            this.Bounds = _bitmapDrawRect;
            this.DoubleBuffered = true;
        }

        private void FrmScreenBitmap_Load(object sender, EventArgs e)
        {
            this.Location = _bitmapDrawRect.Location;
        }


        [Description("绘图事件")]
        private void FrmScreenBitmap_Paint(object sender, PaintEventArgs e)
        {
            if (_bmp == null) return;

            var font = new Font("微软雅黑", 14F, FontStyle.Regular, GraphicsUnit.Point, 134);

            var g = e.Graphics;
            var bitmapDrawRect = new RectangleF(0, 0, _bitmapDrawRect.Width, _bitmapDrawRect.Height);

            g.Clear(Color.Empty);
            g.SmoothingMode = SmoothingMode.HighQuality; //指定抗锯齿的呈现

            //图像绘制区域
            var drawArea = new RectangleF(0, 0, _bmp.Width, _bmp.Height);
            g.DrawImage(_bmp, bitmapDrawRect, drawArea, GraphicsUnit.Pixel);//绘制图像
            Utility.DrawTransparencyFillRect(g, bitmapDrawRect);

            //绘制未选择区域时最大边框区域
            if (_boundType == EBoundType.Wait)
            {
                var lineWidth = Utility.MPen.Width;
                var rect = new RectangleF
                {
                    X = bitmapDrawRect.X + lineWidth,
                    Y = bitmapDrawRect.Y + lineWidth,
                    Width = bitmapDrawRect.Width - lineWidth * 2,
                    Height = bitmapDrawRect.Height - lineWidth * 2,
                };
                Utility.DrawRect(g, rect);
                g.DrawString($"{bitmapDrawRect.Width} x {bitmapDrawRect.Height}", font, new SolidBrush(Color.White), rect.Location);
            }
            else
            {
                var rect = RectFormat(_selectRect); ;
                var p2 = new PointF(rect.X + rect.Width, rect.Y + rect.Height);
                Utility.DrawRect(g, rect.Location, p2);
                g.DrawImage(_bmp, rect, rect, GraphicsUnit.Pixel); //绘制图像
                foreach (EBoundType type in _AllBoundType)
                {
                    if (type == EBoundType.None || type == EBoundType.Updata_5)
                        continue;
                    Utility.DrawFillRect(g, GetBoundRect(type, rect));
                }

                //绘制当前选区的信息
                string text = $"{rect.Width} x {rect.Height}";
                var textLocation = rect.Location;
                var textHeight = (int)g.MeasureString(text, font).Height;
                textLocation.Y -= textHeight;
                if (textLocation.Y < textHeight)
                {
                    textLocation.Y = rect.Y;
                }
                g.DrawString(text, font, new SolidBrush(Color.White), textLocation);
            }
        }

        [Description("监控所有按键")]
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Escape)
            {
                Exit();
                return true;
            }
            return false;
        }

        [Description("鼠标按下:选择区域起点")]
        private void Form2_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left) return;

            SetPanControlState(false);

            _mouseDownLocation = e.Location;
            _selectRectLast = _selectRect;

            switch (_boundType)
            {
                case EBoundType.Wait:
                    _boundType = EBoundType.SelectIng;
                    _mouseUpLocation = _mouseDownLocation;
                    break;
                default:
                    _boundType = GetMouseInRectType(_selectRect, e.Location);
                    break;
            }

        }

        [Description("鼠标移动:设置选择区域的尺寸")]
        private void Form2_MouseMove(object sender, MouseEventArgs e)
        {
            _mouseUpLocation = e.Location;
            SetMouseCursor(e.Location);
            switch (_boundType)
            {
                case EBoundType.Updata_1:
                case EBoundType.Updata_2:
                case EBoundType.Updata_3:
                case EBoundType.Updata_4:
                case EBoundType.Updata_6:
                case EBoundType.Updata_7:
                case EBoundType.Updata_8:
                case EBoundType.Updata_9:
                case EBoundType.Updata_5:
                case EBoundType.SelectIng:
                    UpdataSelectRect(_mouseDownLocation, _mouseUpLocation, _boundType);
                    Refresh();
                    break;
            }
        }

        [Description("鼠标抬起:确定选择区域")]
        private void Form2_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left) return;
            _mouseUpLocation = e.Location;
            UpdataSelectRect(_mouseDownLocation, _mouseUpLocation, _boundType);
            _boundType = EBoundType.End;
            _selectRect = RectFormat(_selectRect);
            Refresh();
            SetPanControlState(true);
        }


        [Description("退出截图")]
        private void pic_Exit_Click(object sender, EventArgs e)
        {
            Exit();
        }

        [Description("保存截图")]
        private void pic_Save_Click(object sender, EventArgs e)
        {
            try
            {
                SaveFileDialog dialog = new SaveFileDialog();
                dialog.Filter = "|*.bmp";
                dialog.FileName = "截图";
                var ret = dialog.ShowDialog() == DialogResult.OK;
                if (ret)
                {
                    Bitmap bmp = Utility.GetImageRect(_bmp, _selectRect);
                    string path = dialog.FileName;
                    _bmp.Save(path, ImageFormat.Bmp);
                    Process.Start(path);
                    Exit();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "异常");
            }
        }

        /// <summary>
        /// 更新选择区域参数
        /// </summary>
        private void UpdataSelectRect(Point down, Point up, EBoundType boundType)
        {
            switch (boundType)
            {
                case EBoundType.SelectIng:
                    _selectRect.Location = new Point(Math.Min(down.X, up.X), Math.Min(down.Y, up.Y));
                    _selectRect.Size = new Size(Math.Abs(down.X - up.X), Math.Abs(down.Y - up.Y));
                    break;
                case EBoundType.Updata_1:
                    _selectRect.X = _selectRectLast.X + (up.X - down.X);
                    _selectRect.Y = _selectRectLast.Y + (up.Y - down.Y);
                    _selectRect.Width = _selectRectLast.Width + (down.X - up.X);
                    _selectRect.Height = _selectRectLast.Height + (down.Y - up.Y);
                    break;
                case EBoundType.Updata_2:
                    _selectRect.Y = _selectRectLast.Y + (up.Y - down.Y);
                    _selectRect.Height = _selectRectLast.Height + (down.Y - up.Y);
                    break;
                case EBoundType.Updata_3:
                    _selectRect.Y = _selectRectLast.Y + (up.Y - down.Y);
                    _selectRect.Width = _selectRectLast.Width + (up.X - down.X);
                    _selectRect.Height = _selectRectLast.Height + (down.Y - up.Y);
                    break;
                case EBoundType.Updata_4:
                    _selectRect.X = _selectRectLast.X + (up.X - down.X);
                    _selectRect.Width = _selectRectLast.Width + (down.X - up.X);
                    break;
                case EBoundType.Updata_6:
                    _selectRect.Width = _selectRectLast.Width + (up.X - down.X);
                    break;
                case EBoundType.Updata_7:
                    _selectRect.X = _selectRectLast.X + (up.X - down.X);
                    _selectRect.Width = _selectRectLast.Width + (down.X - up.X);
                    _selectRect.Height = _selectRectLast.Height + (up.Y - down.Y);
                    break;
                case EBoundType.Updata_8:
                    _selectRect.Height = _selectRectLast.Height + (up.Y - down.Y);
                    break;
                case EBoundType.Updata_9:
                    _selectRect.Width = _selectRectLast.Width + (up.X - down.X);
                    _selectRect.Height = _selectRectLast.Height + (up.Y - down.Y);
                    break;
                case EBoundType.Updata_5:
                    _selectRect.X = _selectRectLast.X + up.X - down.X;
                    _selectRect.Y = _selectRectLast.Y + up.Y - down.Y;
                    break;
            }

        }

        private Rectangle RectFormat(Rectangle rect)
        {

            if (rect.Width < _bitmapDrawRect.X)
            {
                rect.X += rect.Width;
                rect.Width = Math.Abs(rect.Width);
            }

            if (rect.Height < _bitmapDrawRect.Y)
            {
                rect.Y += rect.Height;
                rect.Height = Math.Abs(rect.Height);
            }

            rect.Location = new Point(Math.Min(Math.Max(0, rect.X), _bitmapDrawRect.Width - rect.Width), Math.Min(Math.Max(0, rect.Y), _bitmapDrawRect.Height - rect.Height));

            return rect;
        }

        /// <summary>
        /// 设置鼠标指针样式
        /// </summary>
        private void SetMouseCursor(Point mouseLotion)
        {
            var cursor = Cursors.Arrow;
            switch (GetMouseInRectType(_selectRect, mouseLotion))
            {
                case EBoundType.Updata_1:
                case EBoundType.Updata_9:
                    cursor = Cursors.SizeNWSE;
                    break;
                case EBoundType.Updata_2:
                case EBoundType.Updata_8:
                    cursor = Cursors.SizeNS;
                    break;
                case EBoundType.Updata_3:
                case EBoundType.Updata_7:
                    cursor = Cursors.SizeNESW;
                    break;
                case EBoundType.Updata_4:
                case EBoundType.Updata_6:
                    cursor = Cursors.SizeWE;
                    break;
                case EBoundType.Updata_5:
                    cursor = Cursors.SizeAll;
                    break;
            }
            this.Cursor = cursor;
        }

        private void Exit() => this.Close();

        /// <summary>
        /// 设置控件位置和装填
        /// </summary>
        private void SetPanControlState(bool mouseUp)
        {
            if (mouseUp)
            {
                var location = _selectRect.Location;
                location.X += _selectRect.Width;
                location.Y += _selectRect.Height + 5;
                location.X -= pan_Control.Width + 5;

                location.X = Math.Max(_selectRect.X, location.X);

                if (location.Y + pan_Control.Height > _bitmapDrawRect.Y + _bitmapDrawRect.Height)
                    location.Y = _selectRect.Y - pan_Control.Height - 5;

                if (location.Y < 0)
                    location.Y = _selectRect.Y + _selectRect.Height - pan_Control.Height - 5;

                pan_Control.Location = location;
            }
            pan_Control.Visible = mouseUp;
        }

        /// <summary>
        /// 获取指定区域当前鼠标所在该区域位置的类型
        /// </summary>
        /// <param name="rect"></param>
        /// <returns></returns>
        private EBoundType GetMouseInRectType(Rectangle rect, Point mouseLotion)
        {
            var location = mouseLotion;
            var areaWidth = 3;

            if (!new Rectangle(rect.X - areaWidth, rect.Y - areaWidth, rect.Width + areaWidth * 2, rect.Height + areaWidth * 2).Contains(location))
                return EBoundType.None;
            foreach (EBoundType type in _AllBoundType)
            {
                var newRect = GetBoundRect(type, rect);
                if (newRect.Contains(location))
                {
                    return type;
                }
            }
            return EBoundType.None;
        }

        /// <summary>
        /// 根据选取类型和指定区域获取选取边界的点的小区域
        /// </summary>
        /// <param name="type">选取类型</param>
        /// <param name="rect">指定区域</param>
        /// <param name="isBigRect">边界点区域的大小控制</param>
        /// <returns></returns>
        private Rectangle GetBoundRect(EBoundType type, Rectangle rect)
        {
            switch (type)
            {
                case EBoundType.Updata_1:
                case EBoundType.Updata_2:
                case EBoundType.Updata_3:
                case EBoundType.Updata_4:
                case EBoundType.Updata_6:
                case EBoundType.Updata_7:
                case EBoundType.Updata_8:
                case EBoundType.Updata_9:
                    var location = GetBoundPoint(type, rect);
                    var newRect = GetRecttangleByPoint(location);
                    return newRect;
                case EBoundType.Updata_5:
                    return rect;

                default:
                    throw new Exception("空局域");
            }
        }

        /// <summary>
        /// 获取指定区域的指定边角类型对应的点坐标
        /// </summary>
        private Point GetBoundPoint(EBoundType type, Rectangle rect)
        {
            switch (type)
            {
                case EBoundType.Updata_1:
                    return new Point(rect.X, rect.Y);
                case EBoundType.Updata_2:
                    return new Point(rect.X + rect.Width / 2, rect.Y);
                case EBoundType.Updata_3:
                    return new Point(rect.X + rect.Width, rect.Y);
                case EBoundType.Updata_4:
                    return new Point(rect.X, rect.Y + rect.Height / 2);
                case EBoundType.Updata_5:
                    return new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
                case EBoundType.Updata_6:
                    return new Point(rect.X + rect.Width, rect.Y + rect.Height / 2);
                case EBoundType.Updata_7:
                    return new Point(rect.X, rect.Y + rect.Height);
                case EBoundType.Updata_8:
                    return new Point(rect.X + rect.Width / 2, rect.Y + rect.Height);
                case EBoundType.Updata_9:
                    return new Point(rect.X + rect.Width, rect.Y + rect.Height);
                default:
                    throw new Exception("空局域");
            }
        }

        /// <summary>
        /// 获取边角区域的Rectangle
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        private Rectangle GetRecttangleByPoint(Point p) => new Rectangle
        {
            X = p.X - _boundAreaWidth.Width / 2,
            Y = p.Y - _boundAreaWidth.Height / 2,
            Size = _boundAreaWidth
        };

    }




    /// <summary>
    /// 鼠标所在区域的类型
    /// </summary>
    public enum EBoundType
    {
        None = 1,
        Updata_1,
        Updata_2,
        Updata_3,
        Updata_4,
        Updata_6,
        Updata_7,
        Updata_8,
        Updata_9,

        /// <summary>
        /// 五号区域标识当前选中区域拖动
        /// </summary>
        Updata_5,

        Wait,
        SelectIng,
        End,
    }

}

1.2 FrmScreenShot.Designer.cs

namespace ScreenShot
{
    partial class FrmScreenShot
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.pic_Save = new System.Windows.Forms.PictureBox();
            this.pic_Exit = new System.Windows.Forms.PictureBox();
            this.pan_Control = new System.Windows.Forms.Panel();
            ((System.ComponentModel.ISupportInitialize)(this.pic_Save)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pic_Exit)).BeginInit();
            this.pan_Control.SuspendLayout();
            this.SuspendLayout();
            // 
            // pic_Save
            // 
            this.pic_Save.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left)));
            this.pic_Save.BackColor = System.Drawing.Color.Transparent;
            this.pic_Save.BackgroundImage = global::截取屏幕.Properties.Resources.对错_对;
            this.pic_Save.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
            this.pic_Save.Cursor = System.Windows.Forms.Cursors.Arrow;
            this.pic_Save.Location = new System.Drawing.Point(44, 0);
            this.pic_Save.Margin = new System.Windows.Forms.Padding(0);
            this.pic_Save.Name = "pic_Save";
            this.pic_Save.Size = new System.Drawing.Size(27, 35);
            this.pic_Save.TabIndex = 3;
            this.pic_Save.TabStop = false;
            this.pic_Save.Click += new System.EventHandler(this.pic_Save_Click);
            // 
            // pic_Exit
            // 
            this.pic_Exit.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left)));
            this.pic_Exit.BackColor = System.Drawing.Color.Transparent;
            this.pic_Exit.BackgroundImage = global::截取屏幕.Properties.Resources.对错_错;
            this.pic_Exit.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
            this.pic_Exit.Cursor = System.Windows.Forms.Cursors.Arrow;
            this.pic_Exit.Location = new System.Drawing.Point(9, 0);
            this.pic_Exit.Margin = new System.Windows.Forms.Padding(0);
            this.pic_Exit.Name = "pic_Exit";
            this.pic_Exit.Size = new System.Drawing.Size(27, 35);
            this.pic_Exit.TabIndex = 4;
            this.pic_Exit.TabStop = false;
            this.pic_Exit.Click += new System.EventHandler(this.pic_Exit_Click);
            // 
            // pan_Control
            // 
            this.pan_Control.BackColor = System.Drawing.Color.White;
            this.pan_Control.Controls.Add(this.pic_Exit);
            this.pan_Control.Controls.Add(this.pic_Save);
            this.pan_Control.Location = new System.Drawing.Point(35, 26);
            this.pan_Control.Name = "pan_Control";
            this.pan_Control.Size = new System.Drawing.Size(81, 35);
            this.pan_Control.TabIndex = 5;
            this.pan_Control.Visible = false;
            // 
            // FrmScreenShot
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 20F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
            this.ClientSize = new System.Drawing.Size(716, 593);
            this.Controls.Add(this.pan_Control);
            this.Cursor = System.Windows.Forms.Cursors.Arrow;
            this.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            this.Margin = new System.Windows.Forms.Padding(4);
            this.Name = "FrmScreenShot";
            this.ShowInTaskbar = false;
            this.Text = "Form2";
            this.TopMost = true;
            this.Load += new System.EventHandler(this.FrmScreenBitmap_Load);
            this.Paint += new System.Windows.Forms.PaintEventHandler(this.FrmScreenBitmap_Paint);
            this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form2_MouseDown);
            this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Form2_MouseMove);
            this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Form2_MouseUp);
            ((System.ComponentModel.ISupportInitialize)(this.pic_Save)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pic_Exit)).EndInit();
            this.pan_Control.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.PictureBox pic_Save;
        private System.Windows.Forms.PictureBox pic_Exit;
        private System.Windows.Forms.Panel pan_Control;
    }
}

1.1 Utility.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;


/***********************************************************************************
 * 模块作者:Zheng
 * 创建时间:2023/11/16 14:31:29
 * 功能描述:
 * 
 * 使用说明:
 * 
 * 
 ************************************************************************************/

namespace ScreenShot
{
    public class Utility
    {
        public static Pen MPen = new Pen(Brushes.GreenYellow, 3);

        [DllImport("user32.dll")] //导入user32.dll函数库
        private static extern bool GetCursorPos(out Point lpPoint);//获取鼠标坐标

        /// <summary>
        /// 获取屏幕图片
        /// </summary>
        /// <param name="upperLeftSource">相对于左上角的坐标</param>
        /// <param name="size">图片大小</param>
        /// <returns>截取到的图片</returns>
        public static Bitmap CopyScreenToImage(Point upperLeftSource, Size size)
        {
            // 创建一个bitmap对象并将其设置为屏幕大小
            var bitmap = new Bitmap(size.Width, size.Height);
            // 创建一个Graphics对象并将其设置为
            using (var g = Graphics.FromImage(bitmap))
            {
                // 将整个屏幕绘制到Graphics对象中
                g.CopyFromScreen(upperLeftSource, Point.Empty, size);
            }
            //string path = "1.bmp";
            //bitmap.Save(path, ImageFormat.Bmp);
            //Process.Start(path);
            // 将截图保存为jpg文件
            return bitmap;
        }

        /// <summary>
        /// 获取全屏图片
        /// </summary>
        /// <returns>截取到的图片</returns>
        public static Bitmap CopyScreenToImage(out Rectangle _bitmapDrawRect)
        {
            //todo 
            _bitmapDrawRect = GetAllScreenRect();
            //_bitmapDrawRect = Screen.GetBounds(Point.Empty);
            return CopyScreenToImage(_bitmapDrawRect.Location, _bitmapDrawRect.Size);
        }

        /// <summary>
        /// 获取所有屏幕的区域
        /// </summary>
        /// <returns></returns>
        public static Rectangle GetAllScreenRect()
        {
            int xMin = 0;
            int yMin = 0;
            int xMax = 0;
            int yMax = 0;

            foreach (var screen in Screen.AllScreens)
            {
                xMin = Math.Min(xMin, screen.Bounds.X);
                yMin = Math.Min(yMin, screen.Bounds.Y);

                xMax = Math.Max(xMax, screen.Bounds.X + screen.Bounds.Width);
                yMax = Math.Max(yMax, screen.Bounds.Y + screen.Bounds.Height);
            }

            var rect = new Rectangle(xMin, yMin, xMax - xMin, yMax - yMin);

            return rect;
        }

        /// <summary>
        /// 获取鼠标在屏幕中的坐标
        /// </summary>
        /// <returns></returns>
        public static Point GetMousePose()
        {
            Point mp = new Point();
            GetCursorPos(out mp);
            return mp;
        }

        /// <summary>
        /// 绘制图像(按比例填充)
        /// </summary>
        /// <param name="e">绘画类</param>
        /// <param name="bmp">图像</param>
        /// <param name="size">承载图像的父控件大小</param>
        public static void DrawImage(Graphics e, Bitmap bmp, SizeF size)
        {

            //父控件大小 和Bitmap 的宽高比
            var picByBmpScale = Math.Min(size.Width / bmp.Width, size.Height / bmp.Height);

            //1.图像位置大小
            var bmpPos = new RectangleF
            {
                Width = bmp.Width * picByBmpScale,
                Height = bmp.Height * picByBmpScale
            };
            bmpPos.X = (size.Width - bmpPos.Width) / 2;
            bmpPos.Y = (size.Height - bmpPos.Height) / 2;

            //2.图像绘制区域
            var drawArea = new RectangleF
            {
                X = 0,
                Y = 0,
                Width = bmp.Width,
                Height = bmp.Height
            };

            //绘制图像
            e.SmoothingMode = SmoothingMode.HighQuality;//指定抗锯齿的呈现
            e.DrawImage(bmp, bmpPos, drawArea, GraphicsUnit.Pixel);//绘制图像
        }

        /// <summary>
        /// 根据两点绘制矩形
        /// </summary>
        /// <param name="e"></param>
        /// <param name="firstPoint">第一个点</param>
        /// <param name="secondPoint">第二个点</param>
        public static void DrawRect(Graphics e, PointF firstPoint, PointF secondPoint)
        {
            var x1 = firstPoint.X;
            var y1 = firstPoint.Y;
            var x2 = secondPoint.X;
            var y2 = secondPoint.Y;
            if (x1 > x2)
            {
                x1 = x1 + x2;
                x2 = x1 - x2;
                x1 = x1 - x2;
            }
            if (y1 > y2)
            {
                y1 = y1 + y2;
                y2 = y1 - y2;
                y1 = y1 - y2;
            }

            e.DrawRectangle(MPen, x1, y1, x2 - x1, y2 - y1);
        }

        /// <summary>
        /// 根据两点绘制(填充)矩形
        /// </summary>
        /// <param name="e"></param>
        /// <param name="firstPoint">第一个点</param>
        /// <param name="secondPoint">第二个点</param>
        public static void DrawFillRect(Graphics e, PointF firstPoint, PointF secondPoint)
        {
            var x1 = firstPoint.X;
            var y1 = firstPoint.Y;
            var x2 = secondPoint.X;
            var y2 = secondPoint.Y;
            if (x1 > x2)
            {
                x1 = x1 + x2;
                x2 = x1 - x2;
                x1 = x1 - x2;
            }
            if (y1 > y2)
            {
                y1 = y1 + y2;
                y2 = y1 - y2;
                y1 = y1 - y2;
            }

            SolidBrush brushgreen = new SolidBrush(Color.DarkSlateGray);
            e.FillRectangle(brushgreen, x1, y1, x2 - x1, y2 - y1);
            e.DrawRectangle(MPen, x1, y1, x2 - x1, y2 - y1);
        }

        /// <summary>
        /// 绘制有透明度的(填充)矩形
        /// </summary>
        /// <param name="e"></param>
        /// <param name="rect">第一个点</param>
        public static void DrawTransparencyFillRect(Graphics e, RectangleF rect)
        {
            Color customColor = Color.FromArgb(100, Color.Black);
            SolidBrush shadowBrush = new SolidBrush(customColor);
            e.FillRectangle(shadowBrush, rect);
            //e.DrawRectangles(MPen, new[] { rect });
        }

        /// <summary>
        /// 绘制矩形
        /// </summary>
        /// <param name="e"></param>
        /// <param name="rect">矩形区域</param>
        public static void DrawRect(Graphics e, RectangleF rect)
        {
            e.DrawRectangles(MPen, new[] { rect });
        }

        /// <summary>
        /// 绘制(填充)矩形
        /// </summary>
        /// <param name="e"></param>
        /// <param name="rect">矩形区域</param>
        public static void DrawFillRect(Graphics e, RectangleF rect)
        {
            SolidBrush brushgreen = new SolidBrush(MPen.Color);
            e.FillRectangle(brushgreen, rect);
        }

        /// <summary>
        /// 在控件指定坐标点绘制文本
        /// </summary>
        /// <param name="e"></param>
        /// <param name="point">指定坐标点</param>
        /// <param name="font">文本字体</param>
        /// <param name="text">文本内容</param>
        public static void DrawText(Graphics e, PointF point, Font font, string text)
        {
            SolidBrush Mbrushgreen = new SolidBrush(Color.Red);
            e.DrawString(text, font, Mbrushgreen, point);
        }


        /// <summary>
        /// 获取图像指定区域
        /// </summary>
        /// <param name="sourcebitmap">相对于左上角的坐标</param>
        /// <param name="rect">图片大小</param>
        /// <returns>截取到的图片</returns>
        public static Bitmap GetImageRect(Bitmap sourcebitmap, Rectangle rect)
        {
            // 创建一个bitmap对象
            var bitmap = new Bitmap(rect.Width, rect.Height);
            // 创建一个Graphics对象并将其设置为
            var g = Graphics.FromImage(bitmap);

            // 目标位置 
            var rect1 = new Rectangle(new Point(0, 0), rect.Size);
            // 原图位置 
            var rect2 = new Rectangle(new Point(rect.X, rect.Y), rect.Size);
            g.DrawImage(sourcebitmap, rect1, rect2, GraphicsUnit.Pixel);

            return bitmap;
        }
    }
}

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

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

相关文章

入选《数据结构与算法领域内容帮榜》第44名

入选《数据结构与算法领域内容帮榜》第44名

应用高斯高通滤波器提取图像轮廓

任务要求&#xff1a; 图为HALCON中的例图“tooth_rim”&#xff0c;请用高斯高通滤波器提取图像的轮廓。 任务分析&#xff1a; 图像的边缘对应频谱的高频部分&#xff0c;可以通过构造一个高频滤波器&#xff0c;过滤掉图像的低频部分&#xff0c;从而得到图像的边缘。HALC…

vscode提交代码到Gitee(保姆教程)

Visual Studio Code&#xff08;VSCode&#xff09; 提交代码到Gitee&#xff08;保姆教程&#xff09; 1 环境配置1.1 git本地安装1.2 Vscode安装1.3 配置注册gitee账号 2 Vscode代码提交到Gitee2.1 新建仓库2.2 Vscode提交代码 1 环境配置 电脑需要已经安装好的Vscode已经配…

Axure插件浏览器一键安装:轻松享受高效工作!

Axure插件对原型设计师很熟悉&#xff0c;但由于Axure插件是在国外开发的&#xff0c;所以在安装Axure插件时不仅需要下载中文包&#xff0c;激活步骤也比较繁琐&#xff0c;有时Axure插件与计算机系统不匹配&#xff0c;Axure插件格式不兼容。本文将详细介绍如何安装Axure插件…

泛型类与泛型方法

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 回顾泛型类 我们来回顾…

Dubbo引入Zookeeper等注册中心简介以及DubboAdmin简要介绍,为后续详解Dubbo各种注册中心做铺垫!

文章目录 一&#xff1a;Dubbo注册中心引言 1&#xff1a;什么是Dubbo的注册中心&#xff1f; 2&#xff1a;注册中心关系图解 3&#xff1a;引入注册中心服务执行流程 4&#xff1a;Dubbo注册中心好处 5&#xff1a;注册中心核心作用 二&#xff1a;注册中心实现方案 …

YOLOv5改进: Inner-IoU基于辅助边框的IoU损失,高效结合 GIoU, DIoU, CIoU,SIoU 等 | 2023.11

💡💡💡本文独家改进:Inner-IoU引入尺度因子 ratio 控制辅助边框的尺度大小用于计算损失,并与现有的基于 IoU ( GIoU, DIoU, CIoU,SIoU )损失进行有效结合 推荐指数:5颗星 新颖指数:5颗星 💡💡💡Yolov5/Yolov7魔术师,独家首发创新(原创),适用于…

低压配电柜浪涌保护器综合选型方案

地凯科技低压配电柜是指在额定电压不超过1000V的交流电力系统中&#xff0c;用于接受和分配电能&#xff0c;控制、保护和监测电路的装置。低压配电柜广泛应用于工业、商业、住宅等领域&#xff0c;是电力系统的重要组成部分。 然而&#xff0c;低压配电柜也面临着来自外部和内…

【深度学习】神经网络术语:Epoch、Batch Size和迭代

batchsize&#xff1a;中文翻译为批大小&#xff08;批尺寸&#xff09;。 简单点说&#xff0c;批量大小将决定我们一次训练的样本数目。 batch_size将影响到模型的优化程度和速度。 为什么需要有 Batch_Size : batchsize 的正确选择是为了在内存效率和内存容量之间寻找最…

大白话DDD(DDD黑话终结者)

大白话DDD&#xff08;DDD黑话终结者&#xff09; 一、吐槽的话 相信听过DDD的人有很大一部分都不知道这玩意具体是干嘛的&#xff0c;甚至觉得它有那么一些虚无缥缈。原因之一是但凡讲DDD的&#xff0c;都是一堆特别高大上的概念&#xff0c;然后冠之以一堆让人看不懂的解释…

好用的团队协同办公软件推荐!企业办公必备!

有什么好用的团队协同办公软件可以推荐&#xff1f; 想要的办公软件需要满足“即时通讯”、“多端适配”、“项目管理”、“文件传输”这4大能力。 下面就给大家分享3大类能够满足题主需求的企业级办公软件&#xff0c;免费的付费的都有&#xff0c;也都是侧重的不同领域&…

算法的奥秘:种类、特性及应用详解(算法导论笔记1)

算法&#xff0c;是计算机科学领域的灵魂&#xff0c;是解决问题的重要工具。在算法的世界里&#xff0c;有着各种各样的种类和特性。今天&#xff0c;我将带各位踏上一段探索算法种类的旅程&#xff0c;分享一些常见的算法种类&#xff0c;并给出相应的实践和案例分析。希望通…

opencv-分水岭算法分割

原理 任何一副灰度图像都可以被看成拓扑平面&#xff0c;灰度值高的区域可以被看成是山峰&#xff0c;灰度值低的区域可以被看成是山谷。我们向每一个山谷中灌不同颜色的水。随着水的位的升高&#xff0c;不同山谷的水就会相遇汇合&#xff0c;为了防止不同山谷的水汇合&#x…

年轻有为!2023两院院士增选揭榜 45岁颜宁当选

大家好&#xff0c;我是极智视界&#xff0c;欢迎关注我的公众号&#xff0c;获取我的更多前沿科技分享 邀您加入我的知识星球「极智视界」&#xff0c;星球内有超多好玩的项目实战源码和资源下载&#xff0c;链接&#xff1a;https://t.zsxq.com/0aiNxERDq 通常&#xff0c;两…

梨花声音教育,美食视频配音再次挑战味蕾

在为美食视频进行配音时&#xff0c;配音艺术家的目标是通过声音来激活观众的感官&#xff0c;唤起他们对美味佳肴的渴望&#xff0c;同时展现食物的诱人特色和烹饪的艺术性。配音应当能够描绘美食的丰富细节&#xff0c;传达烹饪的趣味性以及食材的高品质。以下是一些为美食视…

都被“锟斤拷”毒害过,那么究竟是为什么会出现这些奇怪的字符?

不管是在工作中还是生活中&#xff0c;都被“锟斤拷”毒害过&#xff0c;比如这样&#xff1a; 或者这样&#xff1a; 还有这样&#xff1a; 那么究竟是为什么会出现这些奇怪的字符&#xff1f; ASCII编码 在计算机底层都是用0和1进行存储的&#xff0c;ASCII编码将所有的字母…

vivado联合modelsim测试覆盖率

&#xff08;1&#xff09;配置环境 安装modelsim和vivado。点击vivado菜单栏中的tools&#xff0c;在下拉选项中选择compile simulation libraries。simulator选项选择&#xff1a;modelsim simulator。compile library location表示编译库存放的路径。simulator executable p…

【Pytorch】Visualization of Feature Maps(3)

学习参考来自&#xff1a; Image Style Transform–关于图像风格迁移的介绍github&#xff1a;https://github.com/wmn7/ML_Practice/tree/master/2019_06_03 文章目录 风格迁移 风格迁移 风格迁移出处&#xff1a; 《A Neural Algorithm of Artistic Style》&#xff08;ar…

JS 判断元素是否为空

判断元素是否为空&#xff1a; /*** 判断是否为空*/ export function validatenull(val) {if (typeof val boolean) {return false}if (typeof val number) {return false}if (val instanceof Array) {if (val.length0) return true} else if (val instanceof Object) {if (…

PC8223(CC/CV控制)高耐压输入5V/3.4A同步降压电路内建补偿带恒流恒压输出

概述 PC8233&#xff08;替代CX8853&#xff09;是一款同步降压调节器,输出电流高达3.4A,操作范围从8V到32V的宽电源电压。内部补偿要求最低数量现成的标准外部组件。PC8233在CC&#xff08;恒定输出电流&#xff09;模式或CV&#xff08;恒定输出电压&#xff09;模式&#x…