You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现PictureBox1像素色与PictureBox2色尺匹配高亮及颜色名称提取

问题解决方案

一、修复PictureBox2颜色匹配高亮问题

常见问题根源

  • 直接使用颜色精确相等匹配,忽略了图像压缩或色尺本身的细微色差
  • 绘制高亮时未正确清理上一次的绘制痕迹,导致残留黑色块
  • 未处理PictureBox的SizeMode缩放,获取的坐标与实际图像像素不匹配

修正后的实现代码

首先在窗体构造函数中开启双缓冲避免绘制闪烁:

public YourForm()
{
    InitializeComponent();
    pictureBox2.DoubleBuffered = true;
}

然后处理PictureBox1的鼠标移动事件,获取目标颜色并触发PictureBox2重绘:

private Color? currentTargetColor = null;

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    // 校验鼠标位置是否在PictureBox1范围内
    if (e.X < 0 || e.X >= pictureBox1.Width || e.Y < 0 || e.Y >= pictureBox1.Height)
    {
        currentTargetColor = null;
        pictureBox2.Invalidate();
        return;
    }

    Bitmap targetBmp = pictureBox1.Image as Bitmap;
    if (targetBmp == null) return;

    // 计算实际图像像素坐标(适配SizeMode.Zoom)
    float scaleX = (float)targetBmp.Width / pictureBox1.Width;
    float scaleY = (float)targetBmp.Height / pictureBox1.Height;
    int imgX = (int)(e.X * scaleX);
    int imgY = (int)(e.Y * scaleY);

    // 确保坐标不超出图像边界
    imgX = Math.Clamp(imgX, 0, targetBmp.Width - 1);
    imgY = Math.Clamp(imgY, 0, targetBmp.Height - 1);

    currentTargetColor = targetBmp.GetPixel(imgX, imgY);
    pictureBox2.Invalidate();
}

// 处理PictureBox2的Paint事件,绘制高亮区域
private void pictureBox2_Paint(object sender, PaintEventArgs e)
{
    if (currentTargetColor == null) return;

    Color targetColor = currentTargetColor.Value;
    Bitmap rulerBmp = pictureBox2.Image as Bitmap;
    if (rulerBmp == null) return;

    // 设置颜色匹配容差,解决细微色差问题
    int tolerance = 10;

    // 遍历色尺像素,匹配容差内的颜色并绘制半透明高亮
    for (int y = 0; y < rulerBmp.Height; y++)
    {
        for (int x = 0; x < rulerBmp.Width; x++)
        {
            Color pixel = rulerBmp.GetPixel(x, y);
            if (Math.Abs(pixel.R - targetColor.R) <= tolerance &&
                Math.Abs(pixel.G - targetColor.G) <= tolerance &&
                Math.Abs(pixel.B - targetColor.B) <= tolerance)
            {
                e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(128, Color.Yellow)), x, y, 1, 1);
            }
        }
    }
}

核心修复点

  • 用颜色容差匹配替代精确相等,适配图像色差
  • 通过Invalidate()触发重绘,自动清理上一次绘制内容
  • 处理SizeMode缩放,确保获取的是实际图像像素坐标
  • 使用半透明高亮色,保留原色尺可见性,避免黑色块残留

二、提取PictureBox2色尺的颜色名称列表

基于遍历KnownColor的GetNames方法,以下是提取色尺所有唯一颜色名称的实现:

// 遍历KnownColor生成颜色-名称字典
private Dictionary<Color, string> GetKnownColorNames()
{
    var colorDict = new Dictionary<Color, string>();
    foreach (KnownColor knownColor in Enum.GetValues(typeof(KnownColor)))
    {
        Color color = Color.FromKnownColor(knownColor);
        // 排除系统颜色和透明色
        if (!color.IsSystemColor && color.A == 255)
        {
            if (!colorDict.ContainsKey(color))
            {
                colorDict.Add(color, color.Name);
            }
        }
    }
    return colorDict;
}

// 提取色尺中的所有唯一颜色名称
private List<string> ExtractRulerColorNames()
{
    Bitmap rulerBmp = pictureBox2.Image as Bitmap;
    if (rulerBmp == null) return new List<string>();

    var knownColors = GetKnownColorNames();
    var uniqueNames = new HashSet<string>();
    int matchTolerance = 5;

    for (int y = 0; y < rulerBmp.Height; y++)
    {
        for (int x = 0; x < rulerBmp.Width; x++)
        {
            Color pixel = rulerBmp.GetPixel(x, y);
            // 查找容差内匹配的已知颜色
            var matchedColor = knownColors.FirstOrDefault(kvp =>
                Math.Abs(kvp.Key.R - pixel.R) <= matchTolerance &&
                Math.Abs(kvp.Key.G - pixel.G) <= matchTolerance &&
                Math.Abs(kvp.Key.B - pixel.B) <= matchTolerance);

            if (!string.IsNullOrEmpty(matchedColor.Value))
            {
                uniqueNames.Add(matchedColor.Value);
            }
        }
    }

    return uniqueNames.ToList();
}

// 调用示例(如按钮点击事件)
private void btnExtractNames_Click(object sender, EventArgs e)
{
    List<string> colorNames = ExtractRulerColorNames();
    textBox1.Text = string.Join(Environment.NewLine, colorNames);
}

关键说明

  • 使用HashSet自动去重,避免重复颜色名称
  • 加入匹配容差,确保色尺中近似颜色能匹配到标准命名颜色
  • 过滤系统颜色和透明色,只保留通用命名颜色

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:57:03