当前位置: 首页 > news >正文

【笔记】C#得到真正的屏幕大小

闲来研究下非神经网络的computer vision,啥库都不用,先C#试试手撸截屏器,抄起代码来可快了(见下面的代码)。可是使用的时候发现,为啥截屏只截了一部分呢?

        public static Rectangle GetScreenSize(Form from)
        {
            Rectangle rect = Screen.FromControl(from).Bounds;
            return rect;
        }

        public static Bitmap CaptureScreen(Form from, string outputFilename)
        {
            Rectangle rect = GetScreenSize(from);
            using (Bitmap bitmap = new Bitmap(rect.Width, rect.Height))
            {
                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    g.CopyFromScreen(new Point(0, 0), Point.Empty, rect.Size);
                }
                if (outputFilename.Length > 0)
                {
                    bitmap.Save(outputFilename, ImageFormat.Png);
                }
                return bitmap.Clone(new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.PixelFormat.DontCare);
            }
        }

然后搜索了各种方案,要么引用PresentationCore的,要么引用GetDpiForSystem的,一堆乱遭遭的;我只想知道我 2560x1600 的屏幕为啥 Screen 只返回 1707x1067
这个应该是DPI的问题,有点时间又没有接触windows了,想当初还是GetDC的年代…突然意识到我的显示屏的DPI应该是比默认值96高的…
所以查了下,默认原来Windows应用并没有给开启这个high DPI awareness…所以不管用什么API统一都是返回的96
所以这里应该有两种解决方案,一个是直接去读取Windows注册表,找到屏幕缩放比例设置的那个位置,另一个是给应用开启high DPI awareness,就是有一个叫SetProcessDpiAwareness的Windows API,在 Shcore.dll 里:

        [DllImport("shcore.dll")]
        public static extern uint SetProcessDpiAwareness(uint mode);

但是文档里写了,Windows 8.1 / Server 2012R2 才支持,那之前的是不是就不用考虑DPI的问题了,但是也得保证能运行呀。所以改成LoadLibrary的形式:

    static class NativeMethods
    {
        [DllImport("kernel32.dll")]
        public static extern IntPtr LoadLibrary(string dllToLoad);

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

        [DllImport("kernel32.dll")]
        public static extern bool FreeLibrary(IntPtr hModule);
    }

    // v--- in main form scope
        private void EnableDpiAwareness()
        {
            // skip this procedure if Windows version is below
            // Shcore.dll#SetProcessDpiAwareness [min] Windows 8.1 / Windows Server 2012 R2
            IntPtr shcoreDll = NativeMethods.LoadLibrary(@"Shcore.dll");
            if (shcoreDll != IntPtr.Zero) return;
            IntPtr ptrSetProcessDpiAwareness = NativeMethods.GetProcAddress(shcoreDll, "SetProcessDpiAwareness");
            if (ptrSetProcessDpiAwareness != IntPtr.Zero)
            {
                SetProcessDpiAwareness fnSetProcessDpiAwareness = (SetProcessDpiAwareness)System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(ptrSetProcessDpiAwareness, typeof(SetProcessDpiAwareness));
                fnSetProcessDpiAwareness(/* DPI_AWARENESS_SYSTEM_AWARE */ 1);
            }
            NativeMethods.FreeLibrary(shcoreDll);
        }

然后把EnableDpiAwareness放在mainInitializeComponent 之前运行就好了…所有都正常了…

相关文章:

  • SSH远程端口转发
  • 微信支付配置信息如何获取
  • nginx反向代理实例
  • webpack与vite对比
  • Linux中的权限机制
  • 字符串函数【C语言-3】
  • 【Docker】Docker-Compose基础使用说明
  • 用python抠图
  • Java Object类下getClass()方法具有什么功能呢?
  • MongoDB安装使用教程
  • 封装js一些常用的方法(默认值、数组、判空、数值等等)
  • OpenCV之图片预处理方法
  • 跟我学Python图像处理丨傅里叶变换之高通滤波和低通滤波
  • 分布式监控系统——Zabbix(2)部署
  • 机械学习房价预测实战(mse 回归 交叉验证)
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • Angular2开发踩坑系列-生产环境编译
  • canvas 高仿 Apple Watch 表盘
  • es6(二):字符串的扩展
  • JAVA SE 6 GC调优笔记
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • Linux中的硬链接与软链接
  • MySQL-事务管理(基础)
  • MySQL用户中的%到底包不包括localhost?
  • ng6--错误信息小结(持续更新)
  • React-Native - 收藏集 - 掘金
  • windows下mongoDB的环境配置
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 闭包--闭包之tab栏切换(四)
  • 电商搜索引擎的架构设计和性能优化
  • 订阅Forge Viewer所有的事件
  • 浮动相关
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 构建工具 - 收藏集 - 掘金
  • 关于字符编码你应该知道的事情
  • 机器学习 vs. 深度学习
  • 技术:超级实用的电脑小技巧
  • 微信小程序设置上一页数据
  • 我建了一个叫Hello World的项目
  • 小程序button引导用户授权
  • 一、python与pycharm的安装
  • 应用生命周期终极 DevOps 工具包
  • 原生Ajax
  • 智能网联汽车信息安全
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • #if和#ifdef区别
  • #Spring-boot高级
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (二开)Flink 修改源码拓展 SQL 语法
  • (附源码)springboot电竞专题网站 毕业设计 641314
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (离散数学)逻辑连接词
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (转)memcache、redis缓存