Interresting ... :)
Bạn sẽ không chỉ xác định màu gần nhất, bạn cũng sẽ muốn giảm số lượng màu được sử dụng. Bạn không muốn kết thúc bằng một mẫu ghép có sử dụng hàng trăm màu khác nhau ...
Tôi đã đặt cùng một số mã thực hiện điều này ở cấp cơ bản. (Xin lỗi vì nó ở trong C#, tôi hy vọng rằng nó có thể có ích một chút.)
Có một số tinh chỉnh cần thực hiện trước khi phương thức hoạt động tốt, tất nhiên. Phương pháp GetDistance cân nhắc tầm quan trọng của màu sắc, độ bão hòa và độ sáng với nhau, việc tìm ra sự cân bằng tốt nhất giữa những thứ đó tất nhiên là quan trọng để tìm màu gần nhất.
Ngoài ra còn có nhiều việc có thể thực hiện bằng phương pháp giảm bảng màu. Trong ví dụ này, tôi chỉ chọn các màu được sử dụng nhiều nhất, nhưng bạn có thể muốn cân bằng màu sắc trong bảng màu. Điều này có thể được thực hiện bằng cách chọn màu được sử dụng nhiều nhất, giảm số lượng cho các màu còn lại trong danh sách tùy thuộc vào khoảng cách đến màu đã chọn và sau đó sử dụng danh sách.
Lớp HSL chứa một màu DMC, có thể tính toán khoảng cách đến màu khác, và tìm ra màu gần nhất trong một danh sách các màu sắc:
public class Hsl {
public string DmcNumber { get; private set; }
public Color Color { get; private set; }
public float Hue { get; private set; }
public float Saturation { get; private set; }
public float Brightness { get; private set; }
public int Count { get; set; }
public Hsl(Color c) {
DmcNumber = "unknown";
Color = c;
Hue = c.GetHue();
Saturation = c.GetSaturation();
Brightness = c.GetBrightness();
Count = 0;
}
public Hsl(string dmc, int r, int g, int b)
: this(Color.FromArgb(r, g, b))
{
DmcNumber = dmc;
}
private static float AngleDifference(float a1, float a2) {
float a = Math.Abs(a1 - a2);
if (a > 180f) {
a = 360f - a;
}
return a/180f;
}
public float GetDistance(Hsl other) {
return
AngleDifference(Hue, other.Hue) * 3.0f +
Math.Abs(Saturation - other.Saturation) +
Math.Abs(Brightness - other.Brightness) * 4.0f;
}
public Hsl GetNearest(IEnumerable<Hsl> dmcColors) {
Hsl nearest = null;
float nearestDistance = float.MaxValue;
foreach (Hsl dmc in dmcColors) {
float distance = GetDistance(dmc);
if (distance < nearestDistance) {
nearestDistance = distance;
nearest = dmc;
}
}
return nearest;
}
}
Mã này thiết lập một (giảm nặng nề) danh sách các Màu DMC, tải hình ảnh, đếm màu, giảm bảng màu và chuyển đổi hình ảnh. Tất nhiên, bạn cũng muốn lưu thông tin từ bảng màu bị giảm ở đâu đó.
Hsl[] dmcColors = {
new Hsl("blanc", 255, 255, 255),
new Hsl("310", 0, 0, 0),
new Hsl("317", 167, 139, 136),
new Hsl("318", 197, 198, 190),
new Hsl("322", 81, 109, 135),
new Hsl("336", 36, 73, 103),
new Hsl("413", 109, 95, 95),
new Hsl("414", 167, 139, 136),
new Hsl("415", 221, 221, 218),
new Hsl("451", 179, 151, 143),
new Hsl("452", 210, 185, 175),
new Hsl("453", 235, 207, 185),
new Hsl("503", 195, 206, 183),
new Hsl("504", 206, 221, 193),
new Hsl("535", 85, 85, 89)
};
Bitmap image = (Bitmap)Image.FromFile(@"d:\temp\pattern.jpg");
// count colors used
List<Hsl> usage = new List<Hsl>();
for (int y = 0; y < image.Height; y++) {
for (int x = 0; x < image.Width; x++) {
Hsl color = new Hsl(image.GetPixel(x, y));
Hsl nearest = color.GetNearest(dmcColors);
int index = usage.FindIndex(h => h.Color.Equals(nearest.Color));
if (index != -1) {
usage[index].Count++;
} else {
nearest.Count = 1;
usage.Add(nearest);
}
}
}
// reduce number of colors by picking the most used
Hsl[] reduced = usage.OrderBy(c => -c.Count).Take(5).ToArray();
// convert image
for (int y = 0; y < image.Height; y++) {
for (int x = 0; x < image.Width; x++) {
Hsl color = new Hsl(image.GetPixel(x, y));
Hsl nearest = color.GetNearest(reduced);
image.SetPixel(x, y, nearest.Color);
}
}
image.Save(@"d:\temp\pattern.png", System.Drawing.Imaging.ImageFormat.Png);
Đợi? http://stackoverflow.com/questions/492211/is-there-an-easy-way-to-compare-how-close-two-colors-are-to-each-other – bzlm
Bạn có thể sử dụng imagemagick cho điều này, http : //www.imagemagick.org/Usage/quantize/ –
nếu các mũi khâu chéo của bạn không cần phải căn chỉnh thì [dithering] (http://stackoverflow.com/a/36820654/2521214) là bạn của bạn (như bạn có bảng màu cố định).Quantization thường hạn chế số lượng màu sắc từ những gì hình ảnh đầu vào bao gồm nhưng bảng màu của bạn có thể có màu sắc không có trong hình ảnh ở tất cả dẫn đến biến dạng màu sắc kỳ lạ. Để phối màu phù hợp, bạn cần ít nhất: Đỏ, Xanh lục, Xanh lam, Lục lam, Đỏ tươi, Vàng, Đen, Trắng. Nếu bạn có nhiều thì một cường độ tốt hơn nhưng nó cũng hoạt động với cường độ đơn trên mỗi màu. – Spektre