65.9K
CodeProject 正在变化。 阅读更多。
Home

纯 C# .NET 桌面取色器带放大镜

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (24投票s)

2007年1月25日

6分钟阅读

viewsIcon

123878

downloadIcon

3585

一个使用 C# 2.0 编写的桌面取色器,带放大镜功能,不使用 DllImport 或其他 API。

The color pickers window

引言

几年前,我开始用 VB 6.0 编写我的第一个取色器应用程序。这对我很有用,因为它可以帮助我快速为我的网站项目选择颜色。从那时起,我发布了另外两个版本,即免费软件“ColorManager”(你听说过吗?)。

我唯一不喜欢的是:在上一个 .NET 1.x 版本中,我直接通过 DllImport 使用了 API 函数。我之所以使用它们,是因为我最初是在 VB 6.0 中开发的 ColorManager,而且我必须这样做。现在我正在使用 C# 进行开发,并且我想利用 .NET 的强大功能,而不是直接使用 Win32 API。所以我决定用纯 C# 代码重写一个新的 ColorManager 内核版本——就是它了。

我编写了一个用户控件,它就像一个放大镜:将鼠标移到屏幕周围,您会看到光标指向的屏幕部分被放大。如果您不需要,可以禁用显示中的像素和位置视图。单击显示屏将创建一个带有 Alpha 效果的放大镜,它会跟随光标。在移动玻璃激活时,通过鼠标滚轮可以增加或减少其放大值。

示例应用程序是新的 ColorManager 的一个**测试**项目。当窗口失去焦点时(只需单击像素即可选择颜色)或在移动玻璃激活时单击,将选择光标下的当前像素。在选择像素后,窗口将尝试重新获取焦点。最后,RGB 值和颜色的预览将保留在窗口底部,应用程序已准备好选择下一个颜色。

下一步将是让用户能够将值复制到剪贴板,为网站提供十六进制值等等……但这将用于新的 ColorManager ——在这里,您将获得一个用于您自己应用程序的小型用户控件。

Using the Code

您会在文件 MagnifyingGlass.cs 中找到主类 MagnifyingGlass。该类继承自 usercontrol,并提供以下附加属性、方法和事件:

PixelSize 放大倍率。5 表示将一个像素放大到 5x5 像素。(该值应为不能被 2 整除的数字,最小为 3。)
PixelRange 显示范围,从像素开始,到顶部、底部、左侧和右侧(最小为 1)。
ShowPixel 在显示中显示当前像素
ShowPosition 在显示屏的左上角显示当前位置
PosAlign 位置坐标的显示位置(在某个地方,但不在中间)
PosFormat 位置坐标的显示格式(#x#y 用于值)
UpdateTimer 用于以一定间隔更新显示的计时器
PixelColor 当前像素的颜色
DisplayUpdated 在显示屏被计时器或移动玻璃更新后触发此事件
BeforeMakingScreenshot 在移动玻璃生成用于屏幕图像的截图之前触发此事件(也许您想隐藏某些东西?)
AfterMakingScreenshot 在移动玻璃生成截图后触发此事件
MovingGlass 用于移动玻璃的 MagnifyingGlass 实例
SetNewSize(int pixelSize, int pixelRange) 用于设置将用于重新计算控件尺寸的两个值
UseMovingGlass 启用或禁用移动玻璃功能(如果通过构造函数禁用,则始终禁用!)

您不应调整控件的大小:大小将使用 PixelSizePixelRange 设置进行计算。字体取自 Font 属性,字体颜色取自 ForeColor 属性。桌面(或屏幕)外空间以及位置显示背景的颜色取自 BackColor 属性。

我使用特殊的插值模式来禁用缩放图像时的平滑效果

...
e.Graphics.InterpolationMode = System.Drawing.Drawing2D
    .InterpolationMode.NearestNeighbor;
...

如果不进行此设置,在放大的截图视图中很难找到单个像素。

示例代码,用于在窗体上显示具有默认设置的控件(将其放在 form 类内并调用该方法)

private void AddMagnifyingGlassControl()
{
    MagnifyingGlass mg = new MagnifyingGlass();
    // Set the position and maybe other settings to the 
    // "mg" object here
    Controls.Add(mg);
    mg.UpdateTimer.Start();
}

注意:要在设计器中使用该控件,请将该类添加到您的项目中并编译一次。然后您将在 Visual Studio 工具箱中找到该控件。像添加任何其他控件一样将其添加到您的窗体中。

顺便说一句,您可以决定是否要使用移动玻璃功能。只需使用带有布尔值的构造函数即可

// Disable the moving glass
{
    MagnifyingGlass mg = new MagnifyingGlass(false);
}

// Enable the moving glass
{
    MagnifyingGlass mg = new MagnifyingGlass(true);
}
// or:
{
    MagnifyingGlass mg = new MagnifyingGlass();
}

如果您通过构造函数禁用移动玻璃,您将无法稍后启用它(您需要创建一个带有移动玻璃的新 MagnifyingGlass 实例)。在构造时禁用仅用于节省内存,如果您确实不想使用移动玻璃功能。

您也可以在不将固定控件放置到窗体上的情况下,仅使用移动玻璃。示例

private void ShowMovingGlass()
{
    MovingMagnifyingGlass mg = new MovingMagnifyingGlass();
    mg.Show();
    ...
}

有任何建议吗?欢迎提出!

已知bug

  • 我在鼠标滚轮操作方面遇到了一些问题:它似乎可以在 Microsoft 光学鼠标上工作,但在 Logitech 光学鼠标上却不行。对这个问题有什么想法吗?(滚轮在资源管理器等其他 Windows 应用程序中工作得很好。)
  • 像素标记并不精确指向像素。我找不到我的位置计算有任何错误,所以这仍然是一个问题。
  • 如果您使用鼠标滚轮来增加移动玻璃的大小,可能会在右侧和底部出现黑色边框。这是什么错误?我还没有找到。

关注点

编写截图尺寸和显示位置的计算……嗯……(我写的第一版完整代码花了——嗯——大约 30 分钟)。我希望一切都正常。 :)
编辑:我应该花更多时间测试 ;) 第一个 bug 修复已发布。

有人告诉我,在他启动带有放大镜控件的应用程序后,即使 UpdateTimer 已停止,他的显卡 CPU 散热器也运行得更快(也更响)。我不认为这是我的错,但也许有人知道控件在未运行时是否真的会占用图形 CPU 资源??目前,我认为这只是控制散热风扇速度的软件中的一个错误,或者有其他东西需要更多的图形 CPU 资源。

如果您想获取 ColorManager 的当前免费版本(抱歉,没有源代码),您可以从这里下载

历史

2007 年 1 月 24 日

  • 已修复:对 PixelSizePixelRange 的其他设置导致光标显示位置错误
  • 已更改:插值模式现设置为 NearestNeighbor 以获得更好的结果
  • 已添加:PosFormat 属性
  • 已添加:PosAlign 属性
  • 已添加:SetNewSize(int pixelSize, int pixelRange) 方法
  • 已添加:UseMovingGlass 属性
  • 已添加:BeforeMakingScreenshot 事件
  • 已添加:AfterMakingScreenshot 事件
  • 已添加:如果用户单击控件,则添加移动玻璃功能
  • 我进行了一些较小的代码更改,以使一切运行得更好、看起来更好(您还会发现更详细的注释)

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.