闲来无事,就写了一个取色器。原理其实很简单,只需要两步,

  1. 获取鼠标光标的位置,
  2. 获取当前鼠标光标的位置的RGB颜色值。

获取鼠标光标的位置:

System.Drawing.Point p = MousePosition;

获取指定坐标的RGB颜色值,这里我们需要用到1个WIN32的API函数:GetPixel。

GetPixel函数的作用是检索坐标点的像素的RGB颜色值,函数原型为COLORREF GetPixel(HDC hdc, int nXPos, int nYPos)

由于这个是系统提供的API函数,所以在C#中我们无法直接使用,我们需要把它"翻译"一下,以便让C#调用:

/// <summary>
/// 该函数检索指定坐标点的像素的RGB颜色值。
/// </summary>
/// <param name="hDC">设备环境句柄。</param>
/// <param name="nXPos">指定要检查的像素点的逻辑X轴坐标。</param>
/// <param name="nYPos">指定要检查的像素点的逻辑Y轴坐标。</param>
/// <returns>返回值是该象像点的RGB值。如果指定的像素点在当前剪辑区之外;那么返回值是CLR_INVALID。</returns>
[DllImport("gdi32")]
public static extern uint GetPixel(IntPtr hDC, int nXPos, int nYPos);

该函数的X,Y坐标我们已经获取到了,但是设备环境句柄hDC如何获取呢,这里我们又要用到一个WIN32的API函数:GetDC。

GetDC函数的作用是检索显示设备上下文环境的句柄,函数原型为HDC GetDC(HWND hWnd)

"翻译"如下:

/// <summary>
/// 该函数检索一指定窗口的客户区域或整个屏幕的显示设备上下文环境的句柄,
/// 以后可以在GDI函数中使用该句柄来在设备上下文环境中绘图。
/// </summary>
/// <param name="hWnd">设备上下文环境被检索的窗口的句柄,如果该值为NULL,GetDC则检索整个屏幕的设备上下文环境。</param>
/// <returns>如果成功,返回指定窗口客户区的设备上下文环境;如果失败,返回值为Null。</returns>
[DllImport("user32")]
public static extern IntPtr GetDC(IntPtr hWnd);

由于是非托管代码,所以获取到的环境句柄,我们需要手动释放掉。这里又要用到一个API函数:ReleaseDC
ReleaseDC函数的作用是该函数释放设备上下文环境,函数原型为int ReleaseDC(HWND hWnd, HDC hdc)

"翻译"如下:

/// <summary>
/// 该函数释放设备上下文环境(DC)供其他应用程序使用。函数的效果与设备上下文环境类型有关。
/// 它只释放公用的和设备上下文环境,对于类或私有的则无效。
/// </summary>
/// <param name="hWnd">指向要释放的设备上下文环境所在的窗口的句柄。</param>
/// <param name="hDC">指向要释放的设备上下文环境的句柄。</param>
/// <returns>如果释放成功,则返回值为1;如果没有释放成功,则返回值为0。</returns>
[DllImport("user32")]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

接下来开始写代码了。

页面布局如下:

整体的代码也是很简单的。

using System;
using System.Drawing;
using System.Windows.Forms;
using JackyHelper; namespace GetColor
{
public partial class MainForm : Form
{
/// <summary>
/// 显示设备上下文环境的句柄。
/// </summary>
private IntPtr _hdc = IntPtr.Zero; /// <summary>
/// 指向窗口的句柄。
/// </summary>
private readonly IntPtr _hWnd = IntPtr.Zero; public MainForm()
{
InitializeComponent();
} private void timer1_Tick(object sender, EventArgs e)
{
System.Drawing.Point p = MousePosition; tsslCursorPos.Text = string.Format("X:{0},Y:{1}", p.X, p.Y); uint color = Win32Helper.GetPixel(_hdc, p.X, p.Y);
byte r = Win32Helper.GetRValue(color);
byte g = Win32Helper.GetGValue(color);
byte b = Win32Helper.GetBValue(color); txtR.Text = Convert.ToString(r);
txtG.Text = Convert.ToString(g);
txtB.Text = Convert.ToString(b); picColor.BackColor = Color.FromArgb(r, g, b);
txtHexColor.Text = "#" + r.ToString("X").PadLeft(, '') + g.ToString("X").PadLeft(, '') +
b.ToString("X").PadLeft(, '');
} /// <summary>
/// 取色按钮按下
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnGetColor_MouseDown(object sender, MouseEventArgs e)
{
_hdc = Win32Helper.GetDC(_hWnd);
Cursor = Cursors.Cross;
timer1.Enabled = true;
} /// <summary>
/// 取色按钮释放
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnGetColor_MouseUp(object sender, MouseEventArgs e)
{
Win32Helper.ReleaseDC(_hWnd, _hdc);
Cursor = Cursors.Default;
timer1.Enabled = false;
Text = "取色器 By Jacky QQ:773091523";
}
}
}
        /// <summary>
/// 2014-12-5 21:43:51
/// 获取一个RGB颜色值中的红色强度值。
/// </summary>
/// <param name="rgb">指定的RGB颜色值。</param>
/// <returns></returns>
public static byte GetRValue(uint rgb)
{
return (byte)rgb;
} /// <summary>
/// 2014-12-5 21:51:24
/// 获取一个RGB颜色值中的绿色强度值。
/// </summary>
/// <param name="rgb">指定的RGB颜色值。</param>
/// <returns></returns>
public static byte GetGValue(uint rgb)
{
return (byte)(((ushort)(rgb)) >> );
} /// <summary>
/// 2014-12-5 21:52:37
/// 获取一个RGB颜色值中的蓝色强度值。
/// </summary>
/// <param name="rgb">指定的RGB颜色值。</param>
/// <returns></returns>
public static byte GetBValue(uint rgb)
{
return (byte)(rgb >> );
}

不足之处,还望各位大神指正,不胜感激。

C#取色器的更多相关文章

  1. powerpoint取色器有什么用|ppt取色器使用教程

    在使用powerpoint过程中常常发现一些功能我们很少用到,其实是自己不会用的原因,关于powerpoint取色器有什么用呢?接下来我们一起来学一下ppt取色器使用教程. powerpoint取色器 ...

  2. TakeColor 屏幕取色器 8.0 中文绿色版

    软件名称: TakeColor 屏幕取色器软件语言: 简体中文授权方式: 免费软件运行环境: Win8 / Win7 / Vista / WinXP软件大小: 210KB图片预览: 软件简介:使用方便 ...

  3. Win10手记-取色器ColorPicker的实现

    最近个人项目需要用到ColorPicker,但是适用于WinRT和Win10的基本没用,所以只能自己造轮子了. 平台环境 Windows 10 Visual Studio 2015 思路 确定需求后, ...

  4. ColorPix——到目前为止最好用的屏幕取色器

    分享一个颜色取色器网页.PPT.EXCEL配色不再烦恼 简单易用 大家做商业.企业报告的时候是不是经常遇到要调色的困扰呢?PPT.EXCEL等颜色选取会对报告有质的影响!!要更专业要更有美感!给大家分 ...

  5. Arava: 用 swing 写一个取色器

    备哥以前发我了一个小工具,TakeColor 取色器.来复刻一个吧. 分析一下:顶部是菜单,左侧框显示当前鼠标所在的颜色(下面显示当前坐标和颜色值,默认RGB),中间框显示鼠标周围区域,右侧显示取色的 ...

  6. iOS转场弹窗、网易云音乐动效、圆环取色器、Loading效果等源码

    iOS精选源码 view controller transition and popover (控制器转场和弹窗) UITableView头部悬停+UITableView侧滑嵌套 一行代码集成时间选择 ...

  7. Mac下好用的取色器 Sip

    总有很多东西,你只是望一眼就已经神魂颠倒.措施有这样的App做的真的是用心的很,养眼,触发你内心冲动的美感.先留下一个,备忘. 太精致了 操作简单,左上角的有心圆点击就可以在任何地方取色了,取色点会z ...

  8. html 颜色在线取色器

    推荐一个链接 还不错 http://www.atool.org/colorpicker.php

  9. WPF Adorner 简易图片取色器

    回答MSDN问题所写. 使用Adorner+附加属性 图片类(来自这位博主的博客) /// <summary> /// 用于获取位图像素的类 /// </summary> pu ...

随机推荐

  1. OpenFlow协议中如何提高交换机流表的匹配成功率

    写在前面 这段时间一直在研究如何提高流表空间的利用率.一直没能想到好的idea.有一篇文献中比较了现有研究中提到的手段,在这里记录一下都有哪些类型的手段以及这些手段存在的不足.这些手段不仅局限于如何提 ...

  2. NOIP计划与展望

        进入高中一个月了,NOIP这项尤为重要的赛事也即将到来.     这一个月来,烦恼多过一切,文化课的压力,作业的压力,老师的压力,需要自己一一去克服,前一个问题刚解决,后一个问题又出现,每天走 ...

  3. Meeting HDU - 5521 虚点建图

    Problem Description Bessie and her friend Elsie decide to have a meeting. However, after Farmer John ...

  4. 前端PHP入门-027-数组常用函数-掌握级别

    下面的函数一定要到熟悉甚至到掌握级别. 这些函数,也是面试中基础面试中最爱问到的问题. 函数名 功能 array_combine() 生成一个数组,用一个数组的值作为键名,另一个数组值作为值 rang ...

  5. Mac环境下SVN的配置和使用

    简单记录一下在Mac环境下,SVN的配置步骤和使用相关.(Mac自带了svn的服务器和客户端功能,简单配置一下即可使用) 一.SVN的配置方法 1. 创建一个仓库目录,比如在/Users/你的用户名 ...

  6. My97DatePicker 报错 My97DP is not defined

    https://blog.csdn.net/BoomLee/article/details/80967926

  7. $(window).load与$(document).ready的区别

    刚好今天学了用jQuery实现瀑布流的用法,但加载时发现了一个小小的问题,那就是分别用$(window).load与$(document).ready实现加载时,$(document).ready的布 ...

  8. HDU 1299 基础数论 分解

    给一个数n问有多少种x,y的组合使$\frac{1}{x}+\frac{1}{y}=\frac{1}{n},x<=y$满足,设y = k + n,代入得到$x = \frac{n^2}{k} + ...

  9. 不用注解添加controller抛出No adapter for handler异常

    不用注解添加controller时会抛出No adapter for handler异常. 解决方法:在DispatcherServlet的配置文件(***-servlet.xml)中加入如下两行: ...

  10. 数据库 插入时 碰到NULL报错判断的一种方法(技巧)

    //public static object ToDBNull(object value) 判断插入数据的时候个别参数不能为空的时候做的判断方法 //{ // if (value == null) / ...