找回密码
 立即注册
首页 业界区 业界 c#造个轮子-取色器TakeColor(附源码)

c#造个轮子-取色器TakeColor(附源码)

褐洌 7 天前
缘由
 看过上篇文章《OpenCvSharp基于颜色反差规避FBA面单贴标(2)》的都应该有印象这么一行代码:
  1. // 面单颜色列表(十六进制格式)  
  2. privatestaticreadonly List<string> LabelColors = new List<string>
  3. {     
  4. "#7C7C7C", "#707070", "#5E5E5E", "#8F8F8D", "#5F5F5F", "#CBCBC9","#FFFFFF","#FEFEFE","#FCFCFC" ,"#7B7B7B","#828282","#7D7D7D","#787878","#D7D7D5","#777777","#7F7F7F"  
  5. };
复制代码
   每次有不同颜色或者无法定位的面单,都需要人工补录面单的背景色HEX,那么能不能集成一个工具,自动吸取图片色号保存后,这里能立即生效呢?答案是肯定的!先看看动态效果图:
1.gif


  • 点击取色,跟随鼠标实时显示背景色便于定位
  • 快捷键Alt+C,抓取当前鼠标所在背景色存储到列表并存储到根目录colorHistory.json文件,便于其他地方读取
  • 列表支持右键删除错误颜色(如下图)
  • 其他地方读取抓取的颜色列表
2.png

 保存的json文件格式如下:
  1. [
  2.   "#018DBE",
  3. "#B1C681",
  4. "#03231E",
  5. "#61CB81",
  6. "#00424A",
  7. "#B5BD68",
  8. "#A3D9A3",
  9. "#F68A1E",
  10. "#0E83BA",
  11. "#861B2D",
  12. "#059BBC"
  13. ]
复制代码
  每次抓取都会往json存储当前最新色号,然后其他地方实时读取json即可:
  1. //// 面单颜色列表(十六进制格式)
  2.   //private static readonly List<string> LabelColors = new List<string>
  3. //{
  4. //    "#7C7C7C", "#707070", "#5E5E5E", "#8F8F8D", "#5F5F5F", "#CBCBC9","#FFFFFF","#FEFEFE","#FCFCFC" ,"#7B7B7B","#828282","#7D7D7D","#787878","#D7D7D5","#777777","#7F7F7F"
  5. //};
  6. static List<string> LabelColors = new List<string>();
  7. privatestatic List<string> LoadColorList()
  8.   {
  9.       try
  10.       {
  11.           string historyFilePath = System.Windows.Forms.Application.StartupPath + @"\colorHistory.json";
  12.           if (File.Exists(historyFilePath))
  13.           {
  14.               string json = File.ReadAllText(historyFilePath);
  15.               var hexList = JsonSerializer.Deserialize<List<string>>(json);
  16.               foreach (var hex in hexList)
  17.               {
  18.                   if (!string.IsNullOrEmpty(hex))
  19.                   {
  20.                       LabelColors.Add(hex);
  21.                   }
  22.               }
  23.               return LabelColors;
  24.           }
  25.       }
  26.       catch (Exception ex)
  27.       {
  28.           MessageBox.Show($"加载历史记录失败: {ex.Message}", "错误",
  29.               MessageBoxButtons.OK, MessageBoxIcon.Error);
  30.       }
  31.       returnnull;
  32.   }
复制代码
  
3.png
  1. private List<Color> colorHistory = new List<Color>();
  2.   private MagnifierForm magnifierForm;
  3.   privatestring historyFilePath = "colorHistory.json";
  4.   private ContextMenuStrip historyContextMenu;
复制代码
  
  1. // 初始化右键菜单
  2.    privatevoidInitializeContextMenu()
  3.    {
  4.        historyContextMenu = new ContextMenuStrip();
  5.        ToolStripMenuItem deleteItem = new ToolStripMenuItem("删除选中颜色");
  6.        deleteItem.Click += DeleteItem_Click;
  7.        ToolStripMenuItem clearAllItem = new ToolStripMenuItem("清空所有历史");
  8.        clearAllItem.Click += ClearAllItem_Click;
  9.        ToolStripMenuItem copyItem = new ToolStripMenuItem("复制颜色值");
  10.        copyItem.Click += CopyItem_Click;
  11.        historyContextMenu.Items.AddRange(new ToolStripItem[] {
  12.        copyItem, deleteItem, clearAllItem
  13.           });
  14.        lstHistory.ContextMenuStrip = historyContextMenu;
  15.        LoadColorHistory();
  16.        // 设置ListBox为自绘模式
  17.        lstHistory.DrawMode = DrawMode.OwnerDrawFixed;
  18.        lstHistory.DrawItem += LstHistory_DrawItem;
  19.    }
复制代码
  ListBox实时显示当前吸取的背景色,重绘代码如下:
  1. // 绘制ListBox项
  2. privatevoidLstHistory_DrawItem(object sender, DrawItemEventArgs e)
  3. {
  4.      if (e.Index < 0 || e.Index >= colorHistory.Count) return;
  5.      e.DrawBackground();
  6.      Color color = colorHistory[e.Index];
  7.      string text = $"{ColorToHex(color)} - RGB({color.R},{color.G},{color.B})";
  8.      // 绘制颜色块
  9.      Rectangle colorRect = new Rectangle(e.Bounds.Left + 2, e.Bounds.Top + 2, 20, e.Bounds.Height - 4);
  10.      using (SolidBrush brush = new SolidBrush(color))
  11.      {
  12.          e.Graphics.FillRectangle(brush, colorRect);
  13.      }
  14.      e.Graphics.DrawRectangle(Pens.Black, colorRect);
  15.      // 绘制文本
  16.      Rectangle textRect = new Rectangle(e.Bounds.Left + 25, e.Bounds.Top, e.Bounds.Width - 25, e.Bounds.Height);
  17.      using (SolidBrush textBrush = new SolidBrush(e.ForeColor))
  18.      {
  19.          e.Graphics.DrawString(text, e.Font, textBrush, textRect);
  20.      }
  21.      e.DrawFocusRectangle();
  22. }
复制代码
  RGB和HEX 相互转换
  1. // HEX字符串转Color
  2.   private Color HexToColor(string hex)
  3.   {
  4.       try
  5.       {
  6.           // 移除#号
  7.           hex = hex.Replace("#", "");
  8.           // 处理3位HEX
  9.           if (hex.Length == 3)
  10.           {
  11.               hex = $"{hex[0]}{hex[0]}{hex[1]}{hex[1]}{hex[2]}{hex[2]}";
  12.           }
  13.           // 处理6位HEX
  14.           if (hex.Length == 6)
  15.           {
  16.               byte r = Convert.ToByte(hex.Substring(0, 2), 16);
  17.               byte g = Convert.ToByte(hex.Substring(2, 2), 16);
  18.               byte b = Convert.ToByte(hex.Substring(4, 2), 16);
  19.               return Color.FromArgb(r, g, b);
  20.           }
  21.           return Color.Empty;
  22.       }
  23.       catch
  24.       {
  25.           return Color.Empty;
  26.       }
  27.   }
  28. // 颜色转HEX
  29. privatestringColorToHex(Color color)
  30.   {
  31.       return$"#{color.R:X2}{color.G:X2}{color.B:X2}";
  32.   }
复制代码
  
结束语
感谢各位耐心查阅! 如果您有更好的想法欢迎一起交流,有不懂的也可以微信公众号联系博主,作者公众号会经常发一些实用的小工具和demo源码,需要的可以去看看!另外,如果觉得本篇博文对您或者身边朋友有帮助的,麻烦点个关注!赠人玫瑰,手留余香,您的支持就是我写作最大的动力,感谢您的关注,期待和您一起探讨!再会!(公众号回复“takecolor”获取完整代码)
 

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册