发现很多软件颜色都很养眼,却不知具体的颜色值是多少,好参考一下。于是想做个屏幕取色的东西。不过这个东西纯粹是为了技术目的,用QQ就可以搞到这个颜色值,就连画笔都可以,只不过复杂些罢了。先把效果放上来。如图1。
图1 Color Picker(很土啊)
做这个东西只要解决如下的两个问题:
1. 全局鼠标钩子:做这个东西的唯一一个技术难点,虽然网上有各种C++的DLL实现方式,但是总觉得为了一个HOOK,在C#的项目里建立一个C++的项目感觉很不爽。后来终于找到了不需要新建项目的方法。(下文介绍。)
2. 获取鼠标所在点的颜色值。对于有经验的人来说,这个不是个问题。没有经验的人,Google一下,其实也不是个问题。
微软的一篇帮助文档上信誓旦旦地说“Global hooks are not supported in the .NET framework”。不知害得多少人绕过.NET去实现全局钩子。可就是有人不信这个邪,做出了不需要DLL的C#实现的全局钩子(参见此文)。虽然只限于鼠标、键盘钩子,但也足够用了。
第一个问题算是解决了。再来看第二个问题。屏幕取色。稍稍Google一下就可以知道,用Graphics对象的CopyFromScreen方法就可以了。可是Graphics是Form里的东西,在WPF里没有Graphics对象啊。当然也可以再来个API调用的,不过总感觉直接调用API不好。所以想来想去,还是在这个WPF项目里添加了对System.Drawing的引用。并把它包成了一个类。代码如下。
PointColorPicker
1using System.Windows;
2using System.Windows.Media;
3using Bitmap = System.Drawing.Bitmap;
4using Graphics = System.Drawing.Graphics;
5using Size = System.Drawing.Size;
6
7namespace ColorPicker
8{
9 internal class PointColorPicker
10 {
11 private static Bitmap cache = new Bitmap(1, 1);
12 private static Graphics tempGraphics = Graphics.FromImage(cache);
13
14 /**//// <summary>
15 /// Gets the Color from the screen at the given point.
16 /// </summary>
17 /// <param name="point"></param>
18 /// <returns></returns>
19 public static Color GetColorFromPoint(Point point)
20 {
21 tempGraphics.CopyFromScreen((int)point.X, (int)point.Y, 0, 0, new Size(1, 1));
22
23 return cache.GetPixel(0, 0).Upgrade();
24 }
25 }
26}
1using System.Windows;
2using System.Windows.Media;
3using Bitmap = System.Drawing.Bitmap;
4using Graphics = System.Drawing.Graphics;
5using Size = System.Drawing.Size;
6
7namespace ColorPicker
8{
9 internal class PointColorPicker
10 {
11 private static Bitmap cache = new Bitmap(1, 1);
12 private static Graphics tempGraphics = Graphics.FromImage(cache);
13
14 /**//// <summary>
15 /// Gets the Color from the screen at the given point.
16 /// </summary>
17 /// <param name="point"></param>
18 /// <returns></returns>
19 public static Color GetColorFromPoint(Point point)
20 {
21 tempGraphics.CopyFromScreen((int)point.X, (int)point.Y, 0, 0, new Size(1, 1));
22
23 return cache.GetPixel(0, 0).Upgrade();
24 }
25 }
26}
完整的代码下载