發現很多軟體配色很養眼,卻不知具體色值。QQ、畫圖工具都能取色,但操作較繁瑣。決定自己寫一個螢幕取色工具——純粹為技術練習(見圖一)。
圖一:Color Picker 效果示意
| 問題 | 解決方案 |
|---|---|
| 全域滑鼠鉤子 | MSDN 宣稱「Global hooks not supported in .NET」,但實際上滑鼠/鍵盤鉤子可用純 C# 實現,無需 C++ DLL。參考社群成果,採用 WH_MOUSE_LL 低階鉤子。 |
| 取得滑鼠座標處像素顏色 | 使用 Graphics.CopyFromScreen 截取 1x1 像素區域,再讀取像素值。WPF 無 Graphics,專案加入 System.Drawing 參考並封裝為靜態類別。 |
using System.Windows;
using System.Windows.Media;
using Bitmap = System.Drawing.Bitmap;
using Graphics = System.Drawing.Graphics;
using Size = System.Drawing.Size;
namespace ColorPicker
{
internal static class PointColorPicker
{
// 快取 1x1 Bitmap 避免重複配置記憶體
private static readonly Bitmap _cache = new Bitmap(1, 1);
private static readonly Graphics _graphics = Graphics.FromImage(_cache);
///
/// 取得螢幕指定座標的顏色 (WPF Color 結構)
///
public static Color GetColorFromPoint(Point point)
{
// 從螢幕複製 1x1 像素到快取 Bitmap
_graphics.CopyFromScreen((int)point.X, (int)point.Y, 0, 0, new Size(1, 1));
// 取得像素並轉換為 WPF Color
return _cache.GetPixel(0, 0).ToWpfColor();
}
}
// 擴充方法:System.Drawing.Color → System.Windows.Media.Color
internal static class ColorExtensions
{
public static Color ToWpfColor(this System.Drawing.Color c)
{
return Color.FromArgb(c.A, c.R, c.G, c.B);
}
}
}
Bitmap(1,1) 與 Graphics 物件,避免高頻呼叫時頻繁 GC。Point 為螢幕絕對座標 (裝置獨立像素);CopyFromScreen 需整數像素,直接轉型 (int)。System.Drawing.Common (或 .NET Framework 內建 System.Drawing) 參考。// 1. 安裝全域滑鼠鉤子 (WH_MOUSE_LL)
// 2. 鉤子回呼中取得滑鼠座標 → PointColorPicker.GetColorFromPoint()
// 3. 即時更新 UI:顯示顏色預覽、RGB/HEX 數值
// 4. 使用者點擊螢幕任意處 → 鎖定顏色、複製到剪貼簿
// 5. 釋放鉤子、清理資源
.aco, .ase, JSON)。完整專案原始碼(含鉤子實作、UI、單元測試)可從文末連結下載。