演示地址:
http://codeman35.itongyin.com:19004/demo1.aspx
截图:
using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading; namespace demo_win_extractColor { /// <summary> /// 用于图像分色 /// </summary> public class ExtractImageColor { /// <summary> /// 定义分色的色块 /// </summary> /// <param name="imgPath"></param> /// <param name="delta"></param> /// <param name="count">0代表</param> /// <param name="reduce_brightness"></param> /// <param name="reduce_gradients"></param> public Dictionary<Color, float> ParseColor(Bitmap map, int delta = 16, int count = 0, bool reduce_brightness = true, bool reduce_gradients = true ) { int half_delta = 0; if (delta > 2) half_delta = delta / 2 - 1; var PREVIEW_WIDTH = 150f; var PREVIEW_HEIGHT = 150f; double width = map.Width; double height = map.Height; var scale = Math.Min(PREVIEW_WIDTH / map.Width, PREVIEW_HEIGHT / map.Height); if (scale < 1) { width = Math.Floor(scale * map.Width); height = Math.Floor(scale * map.Height); } var mapNew = new Bitmap(map, (int)width, (int)height); var hexarray = new Dictionary<Color, int>(); var total_pixel_count = 0; for (int y = 0; y < mapNew.Height; y++) { for (int x = 0; x < mapNew.Width; x++) { total_pixel_count++; var color = mapNew.GetPixel(x, y); var newcolor = new int[] { 0, 0, 0 }; if (delta > 1) { newcolor[0] = ((color.R + half_delta) / delta).toint32() * delta; newcolor[1] = ((color.G + half_delta) / delta).toint32() * delta; newcolor[2] = ((color.B + half_delta) / delta).toint32() * delta; newcolor[0] = Math.Min(255, newcolor[0]); newcolor[1] = Math.Min(255, newcolor[1]); newcolor[2] = Math.Min(255, newcolor[2]); } var _color = Color.FromArgb(newcolor[0], newcolor[1], newcolor[2]); if (!hexarray.ContainsKey(_color)) { hexarray[_color] = 1; } else { hexarray[_color]++; } } } if (mapNew != null) mapNew.Dispose(); if (reduce_gradients) { // if you want to *eliminate* gradient variations use: // ksort( & hexarray ); var arr = from o in hexarray orderby o.Value ascending select o; var gradients = new Dictionary<Color, Color>(); foreach (var hex in arr) { Color new_hex = new Color(); if (!gradients.ContainsKey(hex.Key)) { new_hex = _find_adjacent(hex.Key, gradients, delta); gradients[hex.Key] = new_hex; } else { new_hex = gradients[hex.Key]; } if (hex.Key != new_hex) { hexarray[hex.Key] = 0; hexarray[new_hex] += hex.Value; } } } if (reduce_brightness) { // if you want to *eliminate* brightness variations use: // ksort( & hexarray ); var arr = from o in hexarray orderby o.Value ascending select o; var brightness = new Dictionary<Color, Color>(); foreach (var hex in arr) { Color new_hex = new Color(); if (!brightness.ContainsKey(hex.Key)) { new_hex = _normalize(hex.Key, brightness, delta); brightness[hex.Key] = new_hex; } else { new_hex = brightness[hex.Key]; } if (hex.Key != new_hex) { hexarray[hex.Key] = 0; hexarray[new_hex] += hex.Value; } } } var ARR = from o in hexarray orderby o.Value descending select o; var hexarrayP = new Dictionary<Color, float>(); // convert counts to percentages foreach (var key in ARR) { hexarrayP[key.Key] = (float)key.Value / total_pixel_count; } if (count == 0) count = hexarrayP.Count; for (int i = 0; i < count; i++) { } return hexarrayP; } private Color _normalize(Color color, Dictionary<Color, Color> brightness, int delta) { var lowest = 255; var highest = 0; lowest = Math.Min(Math.Min(Math.Min(lowest, color.R), color.G), color.B); highest = Math.Max(Math.Max(Math.Max(highest, color.R), color.G), color.B); // Do not normalize white, black, or shades of grey unless low delta if (lowest == highest) { if (delta <= 32) { if (lowest == 0 || highest >= (255 - delta)) { return color; } } else { return color; } } for (; highest < 256; lowest += delta, highest += delta) { try { if (color.R - lowest < 0) break; if (color.G - lowest < 0) break; if (color.B - lowest < 0) break; Color new_hex = Color.FromArgb(color.R - lowest, color.G - lowest, color.B - lowest); if (brightness.ContainsKey(new_hex)) { // same color, different brightness - use it instead return new_hex; } } catch { } } return color; } private Color _find_adjacent(Color hex, Dictionary<Color, Color> gradients, int delta) { if (hex.R > delta) { Color tmp = Color.FromArgb(hex.R - delta, hex.G, hex.B); if (gradients.ContainsKey(tmp)) return gradients[tmp]; } if (hex.G > delta) { Color tmp = Color.FromArgb(hex.R, hex.G - delta, hex.B); if (gradients.ContainsKey(tmp)) return gradients[tmp]; } if (hex.B > delta) { Color tmp = Color.FromArgb(hex.R, hex.G, hex.B - delta); if (gradients.ContainsKey(tmp)) return gradients[tmp]; } if (hex.R < (255 - delta)) { Color tmp = Color.FromArgb(hex.R + delta, hex.G, hex.B); if (gradients.ContainsKey(tmp)) return gradients[tmp]; } if (hex.G < (255 - delta)) { Color tmp = Color.FromArgb(hex.R, hex.G + delta, hex.B); if (gradients.ContainsKey(tmp)) return gradients[tmp]; } if (hex.B < (255 - delta)) { Color tmp = Color.FromArgb(hex.R, hex.G, hex.B + delta); if (gradients.ContainsKey(tmp)) return gradients[tmp]; } return hex; } } }