• 自己写了个截图工具


    很简单,就是先全屏截图,然后再按需要裁剪就可以了。

    所以,首先要获取桌面的大小,代码如下:

        public class PrimaryScreen
        {
            #region Win32 API
            [DllImport("user32.dll")]
            static extern IntPtr GetDC(IntPtr ptr);
            [DllImport("gdi32.dll")]
            static extern int GetDeviceCaps(
            IntPtr hdc, // handle to DC
            int nIndex // index of capability
            );
            [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
            static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
            #endregion
            #region DeviceCaps常量
            const int HORZRES = 8;
            const int VERTRES = 10;
            const int LOGPIXELSX = 88;
            const int LOGPIXELSY = 90;
            const int DESKTOPVERTRES = 117;
            const int DESKTOPHORZRES = 118;
            #endregion
            #region 属性
            /// <summary>
            /// 获取屏幕分辨率当前物理大小
            /// </summary>
            public static Size WorkingArea
            {
                get
                {
                    IntPtr hdc = GetDC(IntPtr.Zero);
                    Size size = new Size();
                    size.Width = GetDeviceCaps(hdc, HORZRES);
                    size.Height = GetDeviceCaps(hdc, VERTRES);
                    ReleaseDC(IntPtr.Zero, hdc);
                    return size;
                }
            }
            /// <summary>
            /// 当前系统DPI_X 大小 一般为96
            /// </summary>
            public static int DpiX
            {
                get
                {
                    IntPtr hdc = GetDC(IntPtr.Zero);
                    int DpiX = GetDeviceCaps(hdc, LOGPIXELSX);
                    ReleaseDC(IntPtr.Zero, hdc);
                    return DpiX;
                }
            }
            /// <summary>
            /// 当前系统DPI_Y 大小 一般为96
            /// </summary>
            public static int DpiY
            {
                get
                {
                    IntPtr hdc = GetDC(IntPtr.Zero);
                    int DpiX = GetDeviceCaps(hdc, LOGPIXELSY);
                    ReleaseDC(IntPtr.Zero, hdc);
                    return DpiX;
                }
            }
            /// <summary>
            /// 获取真实设置的桌面分辨率大小
            /// </summary>
            public static Size DESKTOP
            {
                get
                {
                    IntPtr hdc = GetDC(IntPtr.Zero);
                    Size size = new Size();
                    size.Width = GetDeviceCaps(hdc, DESKTOPHORZRES);
                    size.Height = GetDeviceCaps(hdc, DESKTOPVERTRES);
                    ReleaseDC(IntPtr.Zero, hdc);
                    return size;
                }
            }
    
            /// <summary>
            /// 获取宽度缩放百分比
            /// </summary>
            public static float ScaleX
            {
                get
                {
                    IntPtr hdc = GetDC(IntPtr.Zero);
                    int t = GetDeviceCaps(hdc, DESKTOPHORZRES);
                    int d = GetDeviceCaps(hdc, HORZRES);
                    float ScaleX = (float)GetDeviceCaps(hdc, DESKTOPHORZRES) / (float)GetDeviceCaps(hdc, HORZRES);
                    ReleaseDC(IntPtr.Zero, hdc);
                    return ScaleX;
                }
            }
            /// <summary>
            /// 获取高度缩放百分比
            /// </summary>
            public static float ScaleY
            {
                get
                {
                    IntPtr hdc = GetDC(IntPtr.Zero);
                    float ScaleY = (float)(float)GetDeviceCaps(hdc, DESKTOPVERTRES) / (float)GetDeviceCaps(hdc, VERTRES);
                    ReleaseDC(IntPtr.Zero, hdc);
                    return ScaleY;
                }
            }
            #endregion
        }

    使用 PrimaryScreen.DESKTOP 就可以获取桌面分辨率的大小了,有了这个大小,就可以开始全屏截图了,代码如下:

    public class ImageHelper
        {
            /// <summary>
            /// 截取全屏
            /// </summary>
            /// <returns></returns>
            public static Bitmap GetScreen()
            {
                Size ScreenSize = PrimaryScreen.DESKTOP;
                Bitmap bmp = new Bitmap(ScreenSize.Width, ScreenSize.Height);
                using (Graphics g = Graphics.FromImage(bmp))
                    g.CopyFromScreen(0, 0, 0, 0, new Size(ScreenSize.Width, ScreenSize.Height));
                return bmp;
            }
    
            /// <summary>
            /// 图像明暗调整
            /// </summary>
            /// <param name="b">原始图</param>
            /// <param name="degree">亮度[-255, 255]</param>
            public static void Lighten(Bitmap b, int degree)
            {
                if (b == null)
                {
                    //return null;
                    return;
                }
    
                if (degree < -255) degree = -255;
                if (degree > 255) degree = 255;
    
                try
                {
    
                    int width = b.Width;
                    int height = b.Height;
    
                    int pix = 0;
    
                    BitmapData data = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    
                    unsafe
                    {
                        byte* p = (byte*)data.Scan0;
                        int offset = data.Stride - width * 3;
                        for (int y = 0; y < height; y++)
                        {
                            for (int x = 0; x < width; x++)
                            {
                                // 处理指定位置像素的亮度
                                for (int i = 0; i < 3; i++)
                                {
                                    pix = p[i] + degree;
    
                                    if (degree < 0) p[i] = (byte)Math.Max(0, pix);
                                    if (degree > 0) p[i] = (byte)Math.Min(255, pix);
    
                                } // i
                                p += 3;
                            } // x
                            p += offset;
                        } // y
                    }
    
                    b.UnlockBits(data);
    
                    //return b;
                }
                catch
                {
                    //return null;
                }
    
            } // end of Lighten
        }

    调用 ImageHelper.GetScreen() 即可以获取全屏截图

    再然后,为了实现区域截图,我们需要把全屏截图放到一个窗体里面进行裁剪,弹出裁剪窗体的代码如下:

    private void button1_Click(object sender, EventArgs e)
    {
        this.Opacity = 0; //先隐藏自己
        Bitmap bitmap = ImageHelper.GetScreen(); //截取全屏
        GetScreenForm frm = new GetScreenForm(bitmap); //准备区域截图
        frm.ShowDialog(); //弹出区域截图界面
        this.Opacity = 1; //显示自己
    }

    区域截图的代码有点多,无非就是鼠标按下、移动、松开的相关处理,以对全屏截图进行裁剪处理,代码如下:

        public partial class GetScreenForm : Form
        {
            /// <summary>
            /// 亮图(原图)
            /// </summary>
            public Bitmap bitmap { get; set; }
    
            /// <summary>
            /// 暗图
            /// </summary>
            public Bitmap bitmap2 { get; set; }
    
            /// <summary>
            /// 屏幕的宽
            /// </summary>
            public int W { get; set; }
            /// <summary>
            /// 屏幕的高
            /// </summary>
            public int H { get; set; }
            /// <summary>
            /// 适用于高DPI的宽度
            /// </summary>
            public int W2 { get; set; }
            /// <summary>
            /// 适用于高DPI的高度
            /// </summary>
            public int H2 { get; set; }
    
            Graphics g;
            Bitmap cache;
            Graphics gMain;
    
            /// <summary>
            /// 构造方法
            /// </summary>
            public GetScreenForm(Bitmap bitmap)
            {
                //亮图 (也就是原图)
                this.bitmap = bitmap;
                this.W = bitmap.Width;
                this.H = bitmap.Height;
    
                //暗图
                this.bitmap2 = new Bitmap(bitmap.Width, bitmap.Height);
                using (Graphics g = Graphics.FromImage(bitmap2))
                    g.DrawImage(bitmap, 0, 0);
                ImageHelper.Lighten(bitmap2, -100);
                //求出适用于高DPI的宽和高
                W2 = (int)(bitmap2.Width * PrimaryScreen.ScaleX);
                H2 = (int)(bitmap2.Height * PrimaryScreen.ScaleY);
                //初始化
                InitializeComponent();
                this.Width = (int)(this.W / PrimaryScreen.ScaleX);
                this.Height = (int)(this.H / PrimaryScreen.ScaleY);
                //绘图相关
                cache = new Bitmap(this.W, this.H);
                gMain = this.CreateGraphics();
                g = Graphics.FromImage(cache);
            }
    
            /// <summary>
            /// 双击关闭
            /// </summary>
            protected override void OnDoubleClick(EventArgs e)
            {
                //获取截图 
                if (SX > int.MinValue && SY > int.MinValue)
                {
                    //获取区域
                    int x1 = SX, x2 = SX + SW;
                    if (x1 > x2) { x2 = x1 + x2; x1 = x2 - x1; x2 = x2 - x1; };
                    int y1 = SY, y2 = SY + SH;
                    if (y1 > y2) { y2 = y1 + y2; y1 = y2 - y1; y2 = y2 - y1; };
                    //截图
                    Bitmap bmp = new Bitmap(x2 - x1, y2 - y1);
                    Graphics g6 = Graphics.FromImage(bmp);
                    g6.DrawImage(bitmap,
                        new Rectangle(0, 0, bmp.Width, bmp.Height),
                        new Rectangle((int)(x1 * PrimaryScreen.ScaleX), (int)(y1 * PrimaryScreen.ScaleY), (int)((x2 - x1) * PrimaryScreen.ScaleX), (int)((y2 - y1) * PrimaryScreen.ScaleY)),
                        GraphicsUnit.Pixel);
                    bmp.Save("x.jpg", ImageFormat.Jpeg);
                }
                this.Close();
            }
    
            private void GetScreenForm_Load(object sender, EventArgs e)
            {
    
            }
    
            protected override void OnShown(EventArgs e)
            {
                DrawForm();
            }
    
            void DrawForm()
            {
                //画暗图
                g.DrawImage(bitmap2,
                    new Rectangle(0, 0, W, H),   //目标
                    new Rectangle(0, 0, W2, H2), //
                    GraphicsUnit.Pixel);
    
                //画亮图
                if (SX > int.MinValue && SY > int.MinValue)
                {
                    g.DrawImage(bitmap,
                        new Rectangle(SX, SY, SW, SH),
                        new Rectangle((int)(SX * PrimaryScreen.ScaleX), (int)(SY * PrimaryScreen.ScaleY), (int)(SW * PrimaryScreen.ScaleX), (int)(SH * PrimaryScreen.ScaleY)),
                        GraphicsUnit.Pixel);
                    //new Rectangle(SX, SY, SW, SH),   //目标
                    //new Rectangle(SX, SY, SW, SH),   ////GraphicsUnit.Pixel);
                }
    
                //翻转
                gMain.DrawImage(cache, 0, 0);
            }
    
            /// <summary>
            /// 选择的区域
            /// </summary>
            public int SX { get; set; } = int.MinValue;
            public int SY { get; set; } = int.MinValue;
            public int SW { get; set; }
            public int SH { get; set; }
    
            /// <summary>
            /// 工作类型 0未工作 1画框 2移框
            /// </summary>
            public int WorkType { get; set; }
    
            /// <summary>
            /// 移动的起点
            /// </summary>
            public int MoveX { get; set; }
            public int MoveY { get; set; }
    
            protected override void OnMouseDown(MouseEventArgs e)
            {
                //判断是不是点击在框里
                bool inside = false;
                if (SX > int.MinValue && SY > int.MinValue)
                {
                    int x1 = SX, x2 = SX + SW;
                    if (x1 > x2) { x2 = x1 + x2; x1 = x2 - x1; x2 = x2 - x1; };
                    int y1 = SY, y2 = SY + SH;
                    if (y1 > y2) { y2 = y1 + y2; y1 = y2 - y1; y2 = y2 - y1; };
                    if (e.X > x1 && e.X < x2
                        && e.Y > y1 && e.Y < y2)
                    {
                        inside = true;
                    }
                }
                if (inside)
                {
                    //在框里,则进行移框
                    this.MoveX = e.X;
                    this.MoveY = e.Y;
                    this.WorkType = 2;
                    DrawForm();
                }
                else
                {
                    //在框外,则重新画框
                    this.SX = e.X;
                    this.SY = e.Y;
                    this.SW = 0;
                    this.SH = 0;
                    this.WorkType = 1;
                    DrawForm();
                }
            }
    
            protected override void OnMouseMove(MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Left)
                {
                    if (this.WorkType == 1)
                    {
                        //画框
                        this.SW = e.X - this.SX;
                        this.SH = e.Y - this.SY;
                    }
                    else
                    {
                        //移框
                        this.SX += e.X - this.MoveX;
                        this.SY += e.Y - this.MoveY;
                        this.MoveX = e.X;
                        this.MoveY = e.Y;
                    }
                    DrawForm();
                }
            }
    
            protected override void OnMouseUp(MouseEventArgs e)
            {
                if (this.WorkType == 1)
                {
                    this.SW = e.X - this.SX;
                    this.SH = e.Y - this.SY;
                }
                this.WorkType = 0;
                DrawForm();
            }
        }

    提供源代码给大家玩玩,点这里下载源代码

  • 相关阅读:
    Lua/AHK socket tcp telnet
    Lua wait sleep
    Lua io.open read write seek flush setvbuf append
    stream file 文件 数据流
    AHK通讯 CMD Lua IPC
    零散 Lua/Excel/''/iup
    Windows Program File(x86) 路径 环境变量
    条件正则过滤筛选 V2
    条件正则过滤筛选 V1
    python导包出现的问题
  • 原文地址:https://www.cnblogs.com/zhouyou96/p/12164774.html
Copyright © 2020-2023  润新知