C#颜色拾取器

1,目的:

  • 获取屏幕上任意位置像素的色值。

2,知识点:

  • 热键的注册与注销。
 /// <summary>
        /// 热键注册
        /// </summary>
        /// <param name="hWnd">要定义热键的窗口的句柄 </param>
        /// <param name="id">定义热键ID(不能与其它ID重复) </param>
        /// <param name="fsModifiers">标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效 </param>
        /// <param name="vk">定义热键的内容 </param>
        /// <returns>如果函数执行成功,返回值不为0。如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。</returns>
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifiers fsModifiers, Keys vk);
        /// <summary>
        /// 热键注销
        /// </summary>
        /// <param name="hWnd">要取消热键的窗口的句柄  </param>
        /// <param name="id">要取消热键的ID </param>
        /// <returns></returns>
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
  • 颜色的获取。
/// <summary>
        /// 在一个指定设备场景中获取一个像素的RGB值
        /// </summary>
        /// <param name="hDC">设备场景的句柄</param>
        /// <param name="XPos">逻辑坐标中要检查点的X坐标</param>
        /// <param name="YPos">逻辑坐标中要检查点的Y坐标</param>
        /// <returns>返回一个32位包含ARGB的UInt</returns>
        [DllImport("gdi32.dll")]
        static public extern uint GetPixel(IntPtr hDC, int XPos, int YPos);
  • 获取的颜色值(32位Uint 数据类型),A ,R,G,B分布如下:

与常规A,R,G,B排序有所区别,而且获取的Alpha部分始终为0。

3,效果展示:

4,代码:

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        Timer t = new Timer() { Interval = 100 };
        IntPtr displayHwd;

        private void Form1_Load(object sender, EventArgs e)
        {
            APIHelper.RegisterHotKey(this.Handle, 81, KeyModifiers.Shift, Keys.C);
            this.TopMost = checkBox1.Checked;

            t.Tick += T_Tick;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            APIHelper.UnregisterHotKey(this.Handle, 81);
        }
        /// <summary>
        /// 获取color从左至右第4个byte作为Blue值
        /// </summary>
        /// <param name="color"></param>
        /// <returns></returns>
        byte GetBlue(uint color)
        {
            return (byte)(color>>16);
        }
        byte GetGreen(uint color)
        {
            //向右移动8位
            return (byte)(color >> 8);
        }
        byte GetRed(uint color)
        {
            
            return (byte)(color);
        }
        byte GetAlpha(uint color)
        {
            return (byte)(color >> 24);
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            this.TopMost = checkBox1.Checked;
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            if (btnStart.Text == "开始")
            {
                t.Start();
                btnStart.BackColor = Color.LightGreen;
                btnStart.Text = "停止";
              displayHwd=   APIHelper.CreateDC("DISPLAY", null, null, IntPtr.Zero);
            }
            else
            {
                btnStart.Text = "开始";
                t.Stop();
                btnStart.BackColor = SystemColors.Control;
                APIHelper.DeleteDC(displayHwd);
            }
            

               
        }
        protected override void WndProc(ref Message m)
        {
            //WM_HOTKEY=0x0312,热键关联的消息ID
            const int WM_HOTKEY = 0x0312;
            //按快捷键     
            switch (m.Msg)
            {
                case WM_HOTKEY:
                    switch (m.WParam.ToInt32())
                    {
                        case 81:    //按下的是Shift+C  
                            Clipboard.SetText(txtColor.Text);
                            break;
                    }
                    break;
            }
            base.WndProc(ref m);
        }
        List<string> list = new List<string>();
        private void T_Tick(object sender, EventArgs e)
        {
            Point mousePoint=  Control.MousePosition;
            txtPoint.Text = $"X:{mousePoint.X},Y:{mousePoint.Y}";
            if(Control.MouseButtons== MouseButtons.Left)
            {

                uint colorVal = APIHelper.GetPixel(displayHwd, mousePoint.X, mousePoint.Y);
                list.Clear();
                

                byte[] bytes = BitConverter.GetBytes(colorVal);
                BitArray array = new BitArray(bytes);
                foreach (bool bit in array)
                {
                    if (bit)
                    {
                        list.Add("1");
                    }
                    else
                    {
                        list.Add("0");
                    }

                }
                list.Reverse();
                txtMonitor.Text = string.Join(" ", list);
                byte red = GetRed(colorVal);
                byte green = GetGreen(colorVal);
                byte blue = GetBlue(colorVal);
                byte alpha = GetAlpha(colorVal);
                panel1.BackColor = Color.FromArgb( red, green, blue);
                txtColor.Text = ColorTranslator.ToHtml(panel1.BackColor).ToString();
                txtRGB.Text = $"{red},{green},{blue}";
                btnStart.Text = "开始";
                t.Stop();
                btnStart.BackColor = SystemColors.Control;
                APIHelper.DeleteDC(displayHwd);
            }
        }
    }
    [Flags()]
    public enum KeyModifiers
    {
        None = 0,
        Alt = 1,
        Ctrl = 2,
        Shift = 4,
        WindowsKey = 8
    }
    class APIHelper
    {
        /// <summary>
        /// 在一个指定设备场景中获取一个像素的RGB值
        /// </summary>
        /// <param name="hDC">设备场景的句柄</param>
        /// <param name="XPos">逻辑坐标中要检查点的X坐标</param>
        /// <param name="YPos">逻辑坐标中要检查点的Y坐标</param>
        /// <returns>返回一个32位包含ARGB的UInt</returns>
        [DllImport("gdi32.dll")]
        static public extern uint GetPixel(IntPtr hDC, int XPos, int YPos);
        /// <summary>
        /// 为专门设备创建设备场景
        /// </summary>
        /// <param name="driverName">如果此参数为DISPLAY则代表整个屏幕的设备场景,如果为WINSPOOL则访问打印机驱动</param>
        /// <param name="deviceName">所用专门设备的名称</param>
        /// <param name="output">用null给该参数</param>
        /// <param name="lpinitData">DEVMODE,该结构保存初始值</param>
        /// <returns>设备场景的句柄</returns>
        [DllImport("gdi32.dll")]
        static public extern IntPtr CreateDC(string driverName, string deviceName, string output, IntPtr lpinitData);
        /// <summary>
        /// 在一个指定设备场景中获取一个像素的RGB值
        /// </summary>
        /// <param name="DC">设备场景的句柄</param>
        /// <returns></returns>
        [DllImport("gdi32.dll")]
        static public extern bool DeleteDC(IntPtr DC);
        /// <summary>
        /// 热键注册
        /// </summary>
        /// <param name="hWnd">要定义热键的窗口的句柄 </param>
        /// <param name="id">定义热键ID(不能与其它ID重复) </param>
        /// <param name="fsModifiers">标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效 </param>
        /// <param name="vk">定义热键的内容 </param>
        /// <returns>如果函数执行成功,返回值不为0。如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。</returns>
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifiers fsModifiers, Keys vk);
        /// <summary>
        /// 热键注销
        /// </summary>
        /// <param name="hWnd">要取消热键的窗口的句柄  </param>
        /// <param name="id">要取消热键的ID </param>
        /// <returns></returns>
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

       
    }

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

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

相关文章

如何使用Python Flask搭建一个web页面并实现远程访问

文章目录 前言1. 安装部署Flask并制作SayHello问答界面2. 安装Cpolar内网穿透3. 配置Flask的问答界面公网访问地址4. 公网远程访问Flask的问答界面 前言 Flask是一个Python编写的Web微框架&#xff0c;让我们可以使用Python语言快速实现一个网站或Web服务&#xff0c;本期教程…

C++多线程1(复习向笔记)

创建线程以及相关函数 当用thread类创建线程对象绑定函数后&#xff0c;该线程在主线程执行时就已经自动开始执行了,join起到阻塞主线程的作用 #include <iostream> #include <thread> #include <string> using namespace std; //测试函数 void printStrin…

Java强训day10(选择题编程题)

选择题 public class Test01 {public static void main(String[] args) {try{int i 100 / 0;System.out.print(i);}catch(Exception e){System.out.print(1);throw new RuntimeException();}finally{System.out.print(2);}System.out.print(3);} }编程题 题目1 import jav…

day 59 503.下一个更大元素II 42. 接雨水

vector的扩充要熟悉 vector<int> numsT(nums.begin(),nums.end()); nums.insert(nums.end(),numsT.begin(),numsT.end()); class Solution { public:vector<int> nextGreaterElements(vector<int>& nums) {stack<int> st;vector<int> nums…

C++入门(一)— 使用VScode开发简介

文章目录 C 介绍C 擅长领域C 程序是如何开发编译器、链接器和库编译预处理编译阶段汇编阶段链接阶段 安装集成开发环境 &#xff08;IDE&#xff09;配置编译器&#xff1a;构建配置配置编译器&#xff1a;编译器扩展配置编译器&#xff1a;警告和错误级别配置编译器&#xff1…

自动驾驶代客泊车AVP决策规划详细设计

背景 随着产品的不断迭代&#xff0c;外部停车场的铺开&#xff0c;PAVP车辆需要应对的场景将越来越复杂&#xff0c;因此整体算法泛化能力的提升显得尤为关键。为了打磨巡航规划的能力&#xff0c;算法架构应当设计的更为灵活&#xff0c;可以针对使用场景迁入更为先进有效的算…

Springboot 快速集成 ES

1、Springboot 官网给出的版本选择标准 2、选择版本依赖 我的 elasticsearch 服务版本为 7.17.13&#xff0c;所以 springboot 版本我选用 2.7.10 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies<…

电脑上如何压缩图片?这个方法简单又方便

电脑上如何压缩图片&#xff1f;我们在需要压缩图片大小的时候&#xff0c;最经常使用的就是下载安装一些图片处理软件&#xff0c;这样的方法不仅耽误时间&#xff0c;有些软件的操作步骤还特别繁琐&#xff0c;对新手小白非常不友好&#xff0c;所以小编今天就给大家介绍一个…

巴厘行记(四)——乌布漫游

欢迎览阅《巴厘行记》系列文章 巴厘行记巴厘行记&#xff08;一&#xff09;——海神庙 巴厘行记&#xff08;二&#xff09;——乌布之夜 巴厘行记&#xff08;三&#xff09;——Auntie和Mudi 巴厘行记&#xff08;四&#xff09;——乌布漫游 巴厘行记&#xff08;五&a…

Spring MVC 基本知识

知识回顾 Tomcat 是 Servlet 容器&#xff0c;会解析 Java Web 应用下的 WEB-INF/web.xml 文件&#xff0c;得到相关的 Servlet 组件。 原理解析 Spring MVC 实际是定义了一个 DispatcherSevlet 来统一管理当前 Web 应用下的 Path 路径。在 DispatchSevlet 中持有了一个 Spr…

Mybatis-plus原生pages分页未生效的解决方案

文章目录 前言原因1、Mybatis Plus版本的问题2、Mapper.xml文件中SQL语句格式问题3、Mybatis Plus默认分页拦截器问题4、分页参数传参问题5、分页配置的问题 解决方案1、升级对应的Mybatis-plus版本分页插件配置问题3、自定义分页拦截器4、正确的参数5、不同版本的配置文件3.4.…

笨蛋总结JVM

笨蛋总结JVM 由于Java语言将自己的内存控制权交给了虚拟机&#xff0c;所以需要了解虚拟机的运行机制 &#xff08;主要用于回顾JVM&#xff09; 笨蛋总结JVM 笨蛋总结JVM1.运行时数据区域线程私有区域程序计数器Java虚拟机栈本地方法栈 线程共享区域堆方法区 1.2程序计数器…

Jmeter学习系列之二:工具面板必知必会

目录 前言 一、菜单栏 二、功能区 ​编辑 2.读入数据 总结 前言 Jmeter面板一共分为4个区域&#xff0c;分别是菜单栏、功能区、视图区和内容区。 菜单栏&#xff1a;主要功能包括新建测计划&#xff0c;添加线程组、测试脚本&#xff0c;分布式运行相关&#xff0c;查看…

腾讯云4核16G服务器价格,用于幻兽帕鲁Palworld专用

腾讯云幻兽帕鲁服务器4核16G、8核32G和16核64G配置可选&#xff0c;4核16G14M带宽66元一个月、277元3个月&#xff0c;8核32G22M配置115元1个月、345元3个月&#xff0c;16核64G35M配置580元年1个月、1740元3个月、6960元一年&#xff0c;腾讯云百科txybk.com分享腾讯云幻兽帕鲁…

基于JAVA+SpringBoot+Vue的前后端分离的美食分享推荐平台2

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 在当今社会&#xff0…

专注力训练+番茄工作法,拯救工作学习的效率

文章目录 1.丢失的专注力1.1.谁偷走了我的专注力1.2.是时候夺回我的专注力了 2.番茄工作法2.1.历史2.2.使用方式2.3.一些问题和思考 3.总结 1.丢失的专注力 不知道大家有没有遇到过一些无法专注的情况&#xff0c;在学习和工作的时候总是在被各种各样的事情打断&#xff0c;简…

使用WAF防御网络上的隐蔽威胁之反序列化攻击

​ 什么是反序列化 反序列化是将数据结构或对象状态从某种格式转换回对象的过程。这种格式通常是二进制流或者字符串&#xff08;如JSON、XML&#xff09;&#xff0c;它是对象序列化&#xff08;即对象转换为可存储或可传输格式&#xff09;的逆过程。 反序列化的安全风险 反…

机器学习算法实战案例:使用 Transformer 模型进行时间序列预测实战(升级版)

时间序列预测是一个经久不衰的主题&#xff0c;受自然语言处理领域的成功启发&#xff0c;transformer模型也在时间序列预测有了很大的发展。 本文可以作为学习使用Transformer 模型的时间序列预测的一个起点。 文章目录 机器学习算法实战案例系列答疑&技术交流数据集数据…

Kotlin快速入门系列7

Kotlin的数据类、密封类、枚举类 数据类 与Java等语言不同&#xff0c;kotlin创建只包含数据的类时&#xff0c;需要在类名前声明关键字&#xff1a;data。 data class KotlinBean (val brand : String) 在kotlin中&#xff0c;编译器会自动的从主构造函数中根据所有声明的…

[C++]c++判断CPU的类型及支持的指令集

1、利用cpui判断cpu的类型及支持的指令集&#xff0c;可以进行条件编程&#xff1a;&#xff08;InstructionSet.h&#xff09; #pragma once// InstructionSet.cpp // Compile by using: cl /EHsc /W4 InstructionSet.cpp // processor: x86, x64 // Uses the __cpuid intrin…