Создавайте четко разные цвета RGB на графиках

При создании графиков и отображении различных наборов данных обычно рекомендуется различать наборы по цвету. Итак, одна линия красная, следующая - зеленая и так далее. Проблема в том, что когда количество наборов данных неизвестно, необходимо случайным образом генерировать эти цвета, и часто они оказываются очень близко друг к другу (например, зеленый, светло-зеленый).

Есть идеи о том, как это можно решить и как можно было бы генерировать отчетливо разные цвета?

Было бы здорово, если бы какие-либо примеры (не стесняйтесь просто обсудить проблему и решение без примеров, если вам так проще) были в цветах на основе C # и RGB.


person Riri    schedule 21.11.2008    source источник
comment


Ответы (12)


У вас есть три цветовых канала от 0 до 255: R, G и B.

Сначала пройди

0, 0, 255
0, 255, 0
255, 0, 0

Тогда пройдите

0, 255, 255
255, 0, 255
255, 255, 0

Затем разделите на 2 => 128 и начните снова:

0, 0, 128
0, 128, 0
128, 0, 0
0, 128, 128
128, 0, 128
128, 128, 0

Разделить на 2 => 64

В следующий раз прибавьте 64 к 128 => 192

следовать образцу.

Легко программировать и дает довольно четкие цвета.

РЕДАКТИРОВАТЬ: запрос образца кода

Также - добавьте дополнительный узор, как показано ниже, если серый является приемлемым цветом:

255, 255, 255
128, 128, 128 

Есть несколько способов их создания в коде.

Легкий путь

Если вы можете гарантировать, что вам никогда не понадобится больше, чем фиксированное количество цветов, просто сгенерируйте массив цветов по этому шаблону и используйте их:

    static string[] ColourValues = new string[] { 
        "FF0000", "00FF00", "0000FF", "FFFF00", "FF00FF", "00FFFF", "000000", 
        "800000", "008000", "000080", "808000", "800080", "008080", "808080", 
        "C00000", "00C000", "0000C0", "C0C000", "C000C0", "00C0C0", "C0C0C0", 
        "400000", "004000", "000040", "404000", "400040", "004040", "404040", 
        "200000", "002000", "000020", "202000", "200020", "002020", "202020", 
        "600000", "006000", "000060", "606000", "600060", "006060", "606060", 
        "A00000", "00A000", "0000A0", "A0A000", "A000A0", "00A0A0", "A0A0A0", 
        "E00000", "00E000", "0000E0", "E0E000", "E000E0", "00E0E0", "E0E0E0", 
    };

Трудный путь

Если вы не знаете, сколько цветов вам понадобится, приведенный ниже код сгенерирует до 896 цветов с использованием этого шаблона. (896 = 256 * 7/2) 256 - это цветовое пространство на канал, у нас есть 7 шаблонов, и мы останавливаемся, прежде чем перейдем к цветам, разделенным только одним значением цвета.

Я, наверное, усерднее поработал над этим кодом, чем мне нужно. Во-первых, есть генератор интенсивности, который начинается с 255, а затем генерирует значения в соответствии с описанным выше шаблоном. Генератор паттернов просто перебирает семь цветовых паттернов.

using System;

class Program {
    static void Main(string[] args) {
        ColourGenerator generator = new ColourGenerator();
        for (int i = 0; i < 896; i++) {
            Console.WriteLine(string.Format("{0}: {1}", i, generator.NextColour()));
        }
    }
}

public class ColourGenerator {

    private int index = 0;
    private IntensityGenerator intensityGenerator = new IntensityGenerator();

    public string NextColour() {
        string colour = string.Format(PatternGenerator.NextPattern(index),
            intensityGenerator.NextIntensity(index));
        index++;
        return colour;
    }
}

public class PatternGenerator {
    public static string NextPattern(int index) {
        switch (index % 7) {
        case 0: return "{0}0000";
        case 1: return "00{0}00";
        case 2: return "0000{0}";
        case 3: return "{0}{0}00";
        case 4: return "{0}00{0}";
        case 5: return "00{0}{0}";
        case 6: return "{0}{0}{0}";
        default: throw new Exception("Math error");
        }
    }
}

public class IntensityGenerator {
    private IntensityValueWalker walker;
    private int current;

    public string NextIntensity(int index) {
        if (index == 0) {
            current = 255;
        }
        else if (index % 7 == 0) {
            if (walker == null) {
                walker = new IntensityValueWalker();
            }
            else {
                walker.MoveNext();
            }
            current = walker.Current.Value;
        }
        string currentText = current.ToString("X");
        if (currentText.Length == 1) currentText = "0" + currentText;
        return currentText;
    }
}

public class IntensityValue {

    private IntensityValue mChildA;
    private IntensityValue mChildB;

    public IntensityValue(IntensityValue parent, int value, int level) {
        if (level > 7) throw new Exception("There are no more colours left");
        Value = value;
        Parent = parent;
        Level = level;
    }

    public int Level { get; set; }
    public int Value { get; set; }
    public IntensityValue Parent { get; set; }

    public IntensityValue ChildA {
        get {
            return mChildA ?? (mChildA = new IntensityValue(this, this.Value - (1<<(7-Level)), Level+1));
        }
    }

    public IntensityValue ChildB {
        get {
            return mChildB ?? (mChildB = new IntensityValue(this, Value + (1<<(7-Level)), Level+1));
        }
    }
}

public class IntensityValueWalker {

    public IntensityValueWalker() {
        Current = new IntensityValue(null, 1<<7, 1);
    }

    public IntensityValue Current { get; set; }

    public void MoveNext() {
        if (Current.Parent == null) {
            Current = Current.ChildA;
        }
        else if (Current.Parent.ChildA == Current) {
            Current = Current.Parent.ChildB;
        }
        else {
            int levelsUp = 1;
            Current = Current.Parent;
            while (Current.Parent != null && Current == Current.Parent.ChildB) {
                Current = Current.Parent;
                levelsUp++;
            }
            if (Current.Parent != null) {
                Current = Current.Parent.ChildB;
            }
            else {
                levelsUp++;
            }
            for (int i = 0; i < levelsUp; i++) {
                Current = Current.ChildA;
            }

        }
    }
}
person Sam Meldrum    schedule 21.11.2008
comment
Я не полностью следую этому примеру. Может ли кто-нибудь предоставить для этого пример C #? - person McBainUK; 09.02.2010
comment
Надеюсь, что этот пример кода поможет - вероятно, есть более чистый способ пройтись по дереву значений интенсивности, но это был первый удар, который сработал достаточно хорошо. Ваше здоровье. - person Sam Meldrum; 10.02.2010
comment
Обратите внимание, что этот алгоритм будет создавать ОЧЕНЬ похожие пары цветов (особенно в очень темных или светлых областях с низкой насыщенностью). Он хорошо справляется с работой в областях с высокой насыщенностью и легкостью, но пропускает много тонких цветов, которые все еще визуально различимы. - person Phrogz; 23.02.2012
comment
Я закончил тем, что сделал что-то похожее в Javascript - похоже, есть мысленный костыль / ограничивающий реагент, построенный на rgb. Если бы у нас было четыре цветовых канала с 256 вариантами выбора, стали бы мы писать формулы с (* n) дополнительными цветами? Даже в этом случае критика @Phrogz и @dean все равно останется в силе (и поэтому я искал в SO лучший ответ). Должен быть способ захватывать отчетливо разные оттенки на каждом этапе интенсивности. Ответ Phrogz, ниже, находится на правильном пути, но не доступен для таких людей, как я, если мне нужны сотни цветов некоторыми int счетчик. - person ruffin; 21.08.2012
comment
Я добавил ответ, программно решающий вопрос. Этот ответ здесь на самом деле неверен. Когда вы добавляете 128 к смеси. Вы не просто узнаете его с помощью 0. Вы узнаете его с помощью 0 И 255. Цветовой список Easy Way в этом отношении также нарушен. В основном это белый, черный, R, G, B, C, Y, M, постепенно более тусклый и тусклый. - person Tatarize; 03.09.2012

Чтобы реализовать список вариантов, в котором идут ваши цвета, 255 затем используйте все возможности этого вверх, затем добавьте 0 и все шаблоны RGB с этими двумя значениями. Затем добавьте к ним 128 и все комбинации RGB. Потом 64. Потом 192. И т. Д.

В Java

public Color getColor(int i) {
    return new Color(getRGB(i));
}

public int getRGB(int index) {
    int[] p = getPattern(index);
    return getElement(p[0]) << 16 | getElement(p[1]) << 8 | getElement(p[2]);
}

public int getElement(int index) {
    int value = index - 1;
    int v = 0;
    for (int i = 0; i < 8; i++) {
        v = v | (value & 1);
        v <<= 1;
        value >>= 1;
    }
    v >>= 1;
    return v & 0xFF;
}

public int[] getPattern(int index) {
    int n = (int)Math.cbrt(index);
    index -= (n*n*n);
    int[] p = new int[3];
    Arrays.fill(p,n);
    if (index == 0) {
        return p;
    }
    index--;
    int v = index % 3;
    index = index / 3;
    if (index < n) {
        p[v] = index % n;
        return p;
    }
    index -= n;
    p[v      ] = index / n;
    p[++v % 3] = index % n;
    return p;
}

Это будет создавать шаблоны этого типа бесконечно (2 ^ 24) в будущем. Однако после сотни или около того пятен вы, вероятно, не заметите большой разницы между цветом с 0 или 32 вместо синего.

Возможно, вам лучше нормализовать это в другом цветовом пространстве. Цветовое пространство LAB, например, с нормализованными и преобразованными значениями L, A, B. Таким образом, отчетливость цвета проявляется в чем-то более похожем на человеческий глаз.

getElement () меняет порядок байтов 8-битного числа и начинает отсчет с -1, а не с 0 (маскирование с 255). Итак, 255,0,127,192,64, ... по мере того, как число растет, оно перемещает все менее и менее значащие биты, разделяя число.

getPattern () определяет, каким должен быть самый важный элемент в шаблоне (это корень куба). Затем переходит к разбиению 3N² + 3N + 1 различных паттернов, которые включают этот наиболее значимый элемент.

Этот алгоритм выдаст (первые 128 значений):

#FFFFFF 
#000000 
#FF0000 
#00FF00 
#0000FF 
#FFFF00 
#00FFFF 
#FF00FF 
#808080 
#FF8080 
#80FF80 
#8080FF 
#008080 
#800080 
#808000 
#FFFF80 
#80FFFF 
#FF80FF 
#FF0080 
#80FF00 
#0080FF 
#00FF80 
#8000FF 
#FF8000 
#000080 
#800000 
#008000 
#404040 
#FF4040 
#40FF40 
#4040FF 
#004040 
#400040 
#404000 
#804040 
#408040 
#404080 
#FFFF40 
#40FFFF 
#FF40FF 
#FF0040 
#40FF00 
#0040FF 
#FF8040 
#40FF80 
#8040FF 
#00FF40 
#4000FF 
#FF4000 
#000040 
#400000 
#004000 
#008040 
#400080 
#804000 
#80FF40 
#4080FF 
#FF4080 
#800040 
#408000 
#004080 
#808040 
#408080 
#804080 
#C0C0C0 
#FFC0C0 
#C0FFC0 
#C0C0FF 
#00C0C0 
#C000C0 
#C0C000 
#80C0C0 
#C080C0 
#C0C080 
#40C0C0 
#C040C0 
#C0C040 
#FFFFC0 
#C0FFFF 
#FFC0FF 
#FF00C0 
#C0FF00 
#00C0FF 
#FF80C0 
#C0FF80 
#80C0FF 
#FF40C0 
#C0FF40 
#40C0FF 
#00FFC0 
#C000FF 
#FFC000 
#0000C0 
#C00000 
#00C000 
#0080C0 
#C00080 
#80C000 
#0040C0 
#C00040 
#40C000 
#80FFC0 
#C080FF 
#FFC080 
#8000C0 
#C08000 
#00C080 
#8080C0 
#C08080 
#80C080 
#8040C0 
#C08040 
#40C080 
#40FFC0 
#C040FF 
#FFC040 
#4000C0 
#C04000 
#00C040 
#4080C0 
#C04080 
#80C040 
#4040C0 
#C04040 
#40C040 
#202020 
#FF2020 
#20FF20 

Читайте слева направо, сверху вниз. 729 цветов (9³). Итак, все шаблоны до n = 9. Вы заметите, с какой скоростью они начинают конфликтовать. Вариаций WRGBCYMK так много. И это решение, хотя и умное, в основном только использует разные оттенки основных цветов.

Цветовая сетка, 729 16x16

Большая часть противоречий связана с зеленым цветом и тем, насколько он похож на большинство людей. Требование, чтобы все они были максимально разными вначале, а не были достаточно разными, чтобы не быть одного цвета. И основные недоработки идеи, приведшие к образцам основных цветов и идентичным оттенкам.


Использование CIELab2000 Color Space и Distance Routine для случайного выбора и опробования 10 тысяч различных цветов и нахождения максимально удаленного минимального расстояния от предыдущих цветов (в значительной степени определение запроса) позволяет избежать конфликтов дольше, чем в приведенном выше решении:

Максимальное цветовое расстояние

Это можно было бы назвать статическим списком для Easy Way. На создание 729 записей ушло полтора часа:

#9BC4E5
#310106
#04640D
#FEFB0A
#FB5514
#E115C0
#00587F
#0BC582
#FEB8C8
#9E8317
#01190F
#847D81
#58018B
#B70639
#703B01
#F7F1DF
#118B8A
#4AFEFA
#FCB164
#796EE6
#000D2C
#53495F
#F95475
#61FC03
#5D9608
#DE98FD
#98A088
#4F584E
#248AD0
#5C5300
#9F6551
#BCFEC6
#932C70
#2B1B04
#B5AFC4
#D4C67A
#AE7AA1
#C2A393
#0232FD
#6A3A35
#BA6801
#168E5C
#16C0D0
#C62100
#014347
#233809
#42083B
#82785D
#023087
#B7DAD2
#196956
#8C41BB
#ECEDFE
#2B2D32
#94C661
#F8907D
#895E6B
#788E95
#FB6AB8
#576094
#DB1474
#8489AE
#860E04
#FBC206
#6EAB9B
#F2CDFE
#645341
#760035
#647A41
#496E76
#E3F894
#F9D7CD
#876128
#A1A711
#01FB92
#FD0F31
#BE8485
#C660FB
#120104
#D48958
#05AEE8
#C3C1BE
#9F98F8
#1167D9
#D19012
#B7D802
#826392
#5E7A6A
#B29869
#1D0051
#8BE7FC
#76E0C1
#BACFA7
#11BA09
#462C36
#65407D
#491803
#F5D2A8
#03422C
#72A46E
#128EAC
#47545E
#B95C69
#A14D12
#C4C8FA
#372A55
#3F3610
#D3A2C6
#719FFA
#0D841A
#4C5B32
#9DB3B7
#B14F8F
#747103
#9F816D
#D26A5B
#8B934B
#F98500
#002935
#D7F3FE
#FCB899
#1C0720
#6B5F61
#F98A9D
#9B72C2
#A6919D
#2C3729
#D7C70B
#9F9992
#EFFBD0
#FDE2F1
#923A52
#5140A7
#BC14FD
#6D706C
#0007C4
#C6A62F
#000C14
#904431
#600013
#1C1B08
#693955
#5E7C99
#6C6E82
#D0AFB3
#493B36
#AC93CE
#C4BA9C
#09C4B8
#69A5B8
#374869
#F868ED
#E70850
#C04841
#C36333
#700366
#8A7A93
#52351D
#B503A2
#D17190
#A0F086
#7B41FC
#0EA64F
#017499
#08A882
#7300CD
#A9B074
#4E6301
#AB7E41
#547FF4
#134DAC
#FDEC87
#056164
#FE12A0
#C264BA
#939DAD
#0BCDFA
#277442
#1BDE4A
#826958
#977678
#BAFCE8
#7D8475
#8CCF95
#726638
#FEA8EB
#EAFEF0
#6B9279
#C2FE4B
#304041
#1EA6A7
#022403
#062A47
#054B17
#F4C673
#02FEC7
#9DBAA8
#775551
#835536
#565BCC
#80D7D2
#7AD607
#696F54
#87089A
#664B19
#242235
#7DB00D
#BFC7D6
#D5A97E
#433F31
#311A18
#FDB2AB
#D586C9
#7A5FB1
#32544A
#EFE3AF
#859D96
#2B8570
#8B282D
#E16A07
#4B0125
#021083
#114558
#F707F9
#C78571
#7FB9BC
#FC7F4B
#8D4A92
#6B3119
#884F74
#994E4F
#9DA9D3
#867B40
#CED5C4
#1CA2FE
#D9C5B4
#FEAA00
#507B01
#A7D0DB
#53858D
#588F4A
#FBEEEC
#FC93C1
#D7CCD4
#3E4A02
#C8B1E2
#7A8B62
#9A5AE2
#896C04
#B1121C
#402D7D
#858701
#D498A6
#B484EF
#5C474C
#067881
#C0F9FC
#726075
#8D3101
#6C93B2
#A26B3F
#AA6582
#4F4C4F
#5A563D
#E83005
#32492D
#FC7272
#B9C457
#552A5B
#B50464
#616E79
#DCE2E4
#CF8028
#0AE2F0
#4F1E24
#FD5E46
#4B694E
#C5DEFC
#5DC262
#022D26
#7776B8
#FD9F66
#B049B8
#988F73
#BE385A
#2B2126
#54805A
#141B55
#67C09B
#456989
#DDC1D9
#166175
#C1E29C
#A397B5
#2E2922
#ABDBBE
#B4A6A8
#A06B07
#A99949
#0A0618
#B14E2E
#60557D
#D4A556
#82A752
#4A005B
#3C404F
#6E6657
#7E8BD5
#1275B8
#D79E92
#230735
#661849
#7A8391
#FE0F7B
#B0B6A9
#629591
#D05591
#97B68A
#97939A
#035E38
#53E19E
#DFD7F9
#02436C
#525A72
#059A0E
#3E736C
#AC8E87
#D10C92
#B9906E
#66BDFD
#C0ABFD
#0734BC
#341224
#8AAAC1
#0E0B03
#414522
#6A2F3E
#2D9A8A
#4568FD
#FDE6D2
#FEE007
#9A003C
#AC8190
#DCDD58
#B7903D
#1F2927
#9B02E6
#827A71
#878B8A
#8F724F
#AC4B70
#37233B
#385559
#F347C7
#9DB4FE
#D57179
#DE505A
#37F7DD
#503500
#1C2401
#DD0323
#00A4BA
#955602
#FA5B94
#AA766C
#B8E067
#6A807E
#4D2E27
#73BED7
#D7BC8A
#614539
#526861
#716D96
#829A17
#210109
#436C2D
#784955
#987BAB
#8F0152
#0452FA
#B67757
#A1659F
#D4F8D8
#48416F
#DEBAAF
#A5A9AA
#8C6B83
#403740
#70872B
#D9744D
#151E2C
#5C5E5E
#B47C02
#F4CBD0
#E49D7D
#DD9954
#B0A18B
#2B5308
#EDFD64
#9D72FC
#2A3351
#68496C
#C94801
#EED05E
#826F6D
#E0D6BB
#5B6DB4
#662F98
#0C97CA
#C1CA89
#755A03
#DFA619
#CD70A8
#BBC9C7
#F6BCE3
#A16462
#01D0AA
#87C6B3
#E7B2FA
#D85379
#643AD5
#D18AAE
#13FD5E
#B3E3FD
#C977DB
#C1A7BB
#9286CB
#A19B6A
#8FFED7
#6B1F17
#DF503A
#10DDD7
#9A8457
#60672F
#7D327D
#DD8782
#59AC42
#82FDB8
#FC8AE7
#909F6F
#B691AE
#B811CD
#BCB24E
#CB4BD9
#2B2304
#AA9501
#5D5096
#403221
#F9FAB4
#3990FC
#70DE7F
#95857F
#84A385
#50996F
#797B53
#7B6142
#81D5FE
#9CC428
#0B0438
#3E2005
#4B7C91
#523854
#005EA9
#F0C7AD
#ACB799
#FAC08E
#502239
#BFAB6A
#2B3C48
#0EB5D8
#8A5647
#49AF74
#067AE9
#F19509
#554628
#4426A4
#7352C9
#3F4287
#8B655E
#B480BF
#9BA74C
#5F514C
#CC9BDC
#BA7942
#1C4138
#3C3C3A
#29B09C
#02923F
#701D2B
#36577C
#3F00EA
#3D959E
#440601
#8AEFF3
#6D442A
#BEB1A8
#A11C02
#8383FE
#A73839
#DBDE8A
#0283B3
#888597
#32592E
#F5FDFA
#01191B
#AC707A
#B6BD03
#027B59
#7B4F08
#957737
#83727D
#035543
#6F7E64
#C39999
#52847A
#925AAC
#77CEDA
#516369
#E0D7D0
#FCDD97
#555424
#96E6B6
#85BB74
#5E2074
#BD5E48
#9BEE53
#1A351E
#3148CD
#71575F
#69A6D0
#391A62
#E79EA0
#1C0F03
#1B1636
#D20C39
#765396
#7402FE
#447F3E
#CFD0A8
#3A2600
#685AFC
#A4B3C6
#534302
#9AA097
#FD5154
#9B0085
#403956
#80A1A7
#6E7A9A
#605E6A
#86F0E2
#5A2B01
#7E3D43
#ED823B
#32331B
#424837
#40755E
#524F48
#B75807
#B40080
#5B8CA1
#FDCFE5
#CCFEAC
#755847
#CAB296
#C0D6E3
#2D7100
#D5E4DE
#362823
#69C63C
#AC3801
#163132
#4750A6
#61B8B2
#FCC4B5
#DEBA2E
#FE0449
#737930
#8470AB
#687D87
#D7B760
#6AAB86
#8398B8
#B7B6BF
#92C4A1
#B6084F
#853B5E
#D0BCBA
#92826D
#C6DDC6
#BE5F5A
#280021
#435743
#874514
#63675A
#E97963
#8F9C9E
#985262
#909081
#023508
#DDADBF
#D78493
#363900
#5B0120
#603C47
#C3955D
#AC61CB
#FD7BA7
#716C74
#8D895B
#071001
#82B4F2
#B6BBD8
#71887A
#8B9FE3
#997158
#65A6AB
#2E3067
#321301
#FEECCB
#3B5E72
#C8FE85
#A1DCDF
#CB49A6
#B1C5E4
#3E5EB0
#88AEA7
#04504C
#975232
#6786B9
#068797
#9A98C4
#A1C3C2
#1C3967
#DBEA07
#789658
#E7E7C6
#A6C886
#957F89
#752E62
#171518
#A75648
#01D26F
#0F535D
#047E76
#C54754
#5D6E88
#AB9483
#803B99
#FA9C48
#4A8A22
#654A5C
#965F86
#9D0CBB
#A0E8A0
#D3DBFA
#FD908F
#AEAB85
#A13B89
#F1B350
#066898
#948A42
#C8BEDE
#19252C
#7046AA
#E1EEFC
#3E6557
#CD3F26
#2B1925
#DDAD94
#C0B109
#37DFFE
#039676
#907468
#9E86A5
#3A1B49
#BEE5B7
#C29501
#9E3645
#DC580A
#645631
#444B4B
#FD1A63
#DDE5AE
#887800
#36006F
#3A6260
#784637
#FEA0B7
#A3E0D2
#6D6316
#5F7172
#B99EC7
#777A7E
#E0FEFD
#E16DC5
#01344B
#F8F8FC
#9F9FB5
#182617
#FE3D21
#7D0017
#822F21
#EFD9DC
#6E68C4
#35473E
#007523
#767667
#A6825D
#83DC5F
#227285
#A95E34
#526172
#979730
#756F6D
#716259
#E8B2B5
#B6C9BB
#9078DA
#4F326E
#B2387B
#888C6F
#314B5F
#E5B678
#38A3C6
#586148
#5C515B
#CDCCE1
#C8977F

Использование грубой силы (тестирование всех 16 777 216 цветов RGB с помощью CIELab Delta2000 / Начиная с черного) дает серию. Которые начинают конфликтовать около 26, но могут дойти до 30 или 40 при визуальном осмотре и ручном сбросе (что не может быть выполнено с помощью компьютера). Таким образом, делая абсолютный максимум, можно программно создать только пару десятков различных цветов. Дискретный список - ваш лучший выбор. Вы получите больше дискретных цветов со списком, чем программно. Простой способ - лучшее решение, начните смешивать и сопоставлять с другими способами изменения ваших данных, кроме цвета.

Максимально разные

#000000
#00FF00
#0000FF
#FF0000
#01FFFE
#FFA6FE
#FFDB66
#006401
#010067
#95003A
#007DB5
#FF00F6
#FFEEE8
#774D00
#90FB92
#0076FF
#D5FF00
#FF937E
#6A826C
#FF029D
#FE8900
#7A4782
#7E2DD2
#85A900
#FF0056
#A42400
#00AE7E
#683D3B
#BDC6FF
#263400
#BDD393
#00B917
#9E008E
#001544
#C28C9F
#FF74A3
#01D0FF
#004754
#E56FFE
#788231
#0E4CA1
#91D0CB
#BE9970
#968AE8
#BB8800
#43002C
#DEFF74
#00FFC6
#FFE502
#620E00
#008F9C
#98FF52
#7544B1
#B500FF
#00FF78
#FF6E41
#005F39
#6B6882
#5FAD4E
#A75740
#A5FFD2
#FFB167
#009BFF
#E85EBE

Обновление: я продолжал это около месяца, поэтому при брутфорсе 1024. 1024

public static final String[] indexcolors = new String[]{
        "#000000", "#FFFF00", "#1CE6FF", "#FF34FF", "#FF4A46", "#008941", "#006FA6", "#A30059",
        "#FFDBE5", "#7A4900", "#0000A6", "#63FFAC", "#B79762", "#004D43", "#8FB0FF", "#997D87",
        "#5A0007", "#809693", "#FEFFE6", "#1B4400", "#4FC601", "#3B5DFF", "#4A3B53", "#FF2F80",
        "#61615A", "#BA0900", "#6B7900", "#00C2A0", "#FFAA92", "#FF90C9", "#B903AA", "#D16100",
        "#DDEFFF", "#000035", "#7B4F4B", "#A1C299", "#300018", "#0AA6D8", "#013349", "#00846F",
        "#372101", "#FFB500", "#C2FFED", "#A079BF", "#CC0744", "#C0B9B2", "#C2FF99", "#001E09",
        "#00489C", "#6F0062", "#0CBD66", "#EEC3FF", "#456D75", "#B77B68", "#7A87A1", "#788D66",
        "#885578", "#FAD09F", "#FF8A9A", "#D157A0", "#BEC459", "#456648", "#0086ED", "#886F4C",
        "#34362D", "#B4A8BD", "#00A6AA", "#452C2C", "#636375", "#A3C8C9", "#FF913F", "#938A81",
        "#575329", "#00FECF", "#B05B6F", "#8CD0FF", "#3B9700", "#04F757", "#C8A1A1", "#1E6E00",
        "#7900D7", "#A77500", "#6367A9", "#A05837", "#6B002C", "#772600", "#D790FF", "#9B9700",
        "#549E79", "#FFF69F", "#201625", "#72418F", "#BC23FF", "#99ADC0", "#3A2465", "#922329",
        "#5B4534", "#FDE8DC", "#404E55", "#0089A3", "#CB7E98", "#A4E804", "#324E72", "#6A3A4C",
        "#83AB58", "#001C1E", "#D1F7CE", "#004B28", "#C8D0F6", "#A3A489", "#806C66", "#222800",
        "#BF5650", "#E83000", "#66796D", "#DA007C", "#FF1A59", "#8ADBB4", "#1E0200", "#5B4E51",
        "#C895C5", "#320033", "#FF6832", "#66E1D3", "#CFCDAC", "#D0AC94", "#7ED379", "#012C58",
        "#7A7BFF", "#D68E01", "#353339", "#78AFA1", "#FEB2C6", "#75797C", "#837393", "#943A4D",
        "#B5F4FF", "#D2DCD5", "#9556BD", "#6A714A", "#001325", "#02525F", "#0AA3F7", "#E98176",
        "#DBD5DD", "#5EBCD1", "#3D4F44", "#7E6405", "#02684E", "#962B75", "#8D8546", "#9695C5",
        "#E773CE", "#D86A78", "#3E89BE", "#CA834E", "#518A87", "#5B113C", "#55813B", "#E704C4",
        "#00005F", "#A97399", "#4B8160", "#59738A", "#FF5DA7", "#F7C9BF", "#643127", "#513A01",
        "#6B94AA", "#51A058", "#A45B02", "#1D1702", "#E20027", "#E7AB63", "#4C6001", "#9C6966",
        "#64547B", "#97979E", "#006A66", "#391406", "#F4D749", "#0045D2", "#006C31", "#DDB6D0",
        "#7C6571", "#9FB2A4", "#00D891", "#15A08A", "#BC65E9", "#FFFFFE", "#C6DC99", "#203B3C",
        "#671190", "#6B3A64", "#F5E1FF", "#FFA0F2", "#CCAA35", "#374527", "#8BB400", "#797868",
        "#C6005A", "#3B000A", "#C86240", "#29607C", "#402334", "#7D5A44", "#CCB87C", "#B88183",
        "#AA5199", "#B5D6C3", "#A38469", "#9F94F0", "#A74571", "#B894A6", "#71BB8C", "#00B433",
        "#789EC9", "#6D80BA", "#953F00", "#5EFF03", "#E4FFFC", "#1BE177", "#BCB1E5", "#76912F",
        "#003109", "#0060CD", "#D20096", "#895563", "#29201D", "#5B3213", "#A76F42", "#89412E",
        "#1A3A2A", "#494B5A", "#A88C85", "#F4ABAA", "#A3F3AB", "#00C6C8", "#EA8B66", "#958A9F",
        "#BDC9D2", "#9FA064", "#BE4700", "#658188", "#83A485", "#453C23", "#47675D", "#3A3F00",
        "#061203", "#DFFB71", "#868E7E", "#98D058", "#6C8F7D", "#D7BFC2", "#3C3E6E", "#D83D66",
        "#2F5D9B", "#6C5E46", "#D25B88", "#5B656C", "#00B57F", "#545C46", "#866097", "#365D25",
        "#252F99", "#00CCFF", "#674E60", "#FC009C", "#92896B", "#1E2324", "#DEC9B2", "#9D4948",
        "#85ABB4", "#342142", "#D09685", "#A4ACAC", "#00FFFF", "#AE9C86", "#742A33", "#0E72C5",
        "#AFD8EC", "#C064B9", "#91028C", "#FEEDBF", "#FFB789", "#9CB8E4", "#AFFFD1", "#2A364C",
        "#4F4A43", "#647095", "#34BBFF", "#807781", "#920003", "#B3A5A7", "#018615", "#F1FFC8",
        "#976F5C", "#FF3BC1", "#FF5F6B", "#077D84", "#F56D93", "#5771DA", "#4E1E2A", "#830055",
        "#02D346", "#BE452D", "#00905E", "#BE0028", "#6E96E3", "#007699", "#FEC96D", "#9C6A7D",
        "#3FA1B8", "#893DE3", "#79B4D6", "#7FD4D9", "#6751BB", "#B28D2D", "#E27A05", "#DD9CB8",
        "#AABC7A", "#980034", "#561A02", "#8F7F00", "#635000", "#CD7DAE", "#8A5E2D", "#FFB3E1",
        "#6B6466", "#C6D300", "#0100E2", "#88EC69", "#8FCCBE", "#21001C", "#511F4D", "#E3F6E3",
        "#FF8EB1", "#6B4F29", "#A37F46", "#6A5950", "#1F2A1A", "#04784D", "#101835", "#E6E0D0",
        "#FF74FE", "#00A45F", "#8F5DF8", "#4B0059", "#412F23", "#D8939E", "#DB9D72", "#604143",
        "#B5BACE", "#989EB7", "#D2C4DB", "#A587AF", "#77D796", "#7F8C94", "#FF9B03", "#555196",
        "#31DDAE", "#74B671", "#802647", "#2A373F", "#014A68", "#696628", "#4C7B6D", "#002C27",
        "#7A4522", "#3B5859", "#E5D381", "#FFF3FF", "#679FA0", "#261300", "#2C5742", "#9131AF",
        "#AF5D88", "#C7706A", "#61AB1F", "#8CF2D4", "#C5D9B8", "#9FFFFB", "#BF45CC", "#493941",
        "#863B60", "#B90076", "#003177", "#C582D2", "#C1B394", "#602B70", "#887868", "#BABFB0",
        "#030012", "#D1ACFE", "#7FDEFE", "#4B5C71", "#A3A097", "#E66D53", "#637B5D", "#92BEA5",
        "#00F8B3", "#BEDDFF", "#3DB5A7", "#DD3248", "#B6E4DE", "#427745", "#598C5A", "#B94C59",
        "#8181D5", "#94888B", "#FED6BD", "#536D31", "#6EFF92", "#E4E8FF", "#20E200", "#FFD0F2",
        "#4C83A1", "#BD7322", "#915C4E", "#8C4787", "#025117", "#A2AA45", "#2D1B21", "#A9DDB0",
        "#FF4F78", "#528500", "#009A2E", "#17FCE4", "#71555A", "#525D82", "#00195A", "#967874",
        "#555558", "#0B212C", "#1E202B", "#EFBFC4", "#6F9755", "#6F7586", "#501D1D", "#372D00",
        "#741D16", "#5EB393", "#B5B400", "#DD4A38", "#363DFF", "#AD6552", "#6635AF", "#836BBA",
        "#98AA7F", "#464836", "#322C3E", "#7CB9BA", "#5B6965", "#707D3D", "#7A001D", "#6E4636",
        "#443A38", "#AE81FF", "#489079", "#897334", "#009087", "#DA713C", "#361618", "#FF6F01",
        "#006679", "#370E77", "#4B3A83", "#C9E2E6", "#C44170", "#FF4526", "#73BE54", "#C4DF72",
        "#ADFF60", "#00447D", "#DCCEC9", "#BD9479", "#656E5B", "#EC5200", "#FF6EC2", "#7A617E",
        "#DDAEA2", "#77837F", "#A53327", "#608EFF", "#B599D7", "#A50149", "#4E0025", "#C9B1A9",
        "#03919A", "#1B2A25", "#E500F1", "#982E0B", "#B67180", "#E05859", "#006039", "#578F9B",
        "#305230", "#CE934C", "#B3C2BE", "#C0BAC0", "#B506D3", "#170C10", "#4C534F", "#224451",
        "#3E4141", "#78726D", "#B6602B", "#200441", "#DDB588", "#497200", "#C5AAB6", "#033C61",
        "#71B2F5", "#A9E088", "#4979B0", "#A2C3DF", "#784149", "#2D2B17", "#3E0E2F", "#57344C",
        "#0091BE", "#E451D1", "#4B4B6A", "#5C011A", "#7C8060", "#FF9491", "#4C325D", "#005C8B",
        "#E5FDA4", "#68D1B6", "#032641", "#140023", "#8683A9", "#CFFF00", "#A72C3E", "#34475A",
        "#B1BB9A", "#B4A04F", "#8D918E", "#A168A6", "#813D3A", "#425218", "#DA8386", "#776133",
        "#563930", "#8498AE", "#90C1D3", "#B5666B", "#9B585E", "#856465", "#AD7C90", "#E2BC00",
        "#E3AAE0", "#B2C2FE", "#FD0039", "#009B75", "#FFF46D", "#E87EAC", "#DFE3E6", "#848590",
        "#AA9297", "#83A193", "#577977", "#3E7158", "#C64289", "#EA0072", "#C4A8CB", "#55C899",
        "#E78FCF", "#004547", "#F6E2E3", "#966716", "#378FDB", "#435E6A", "#DA0004", "#1B000F",
        "#5B9C8F", "#6E2B52", "#011115", "#E3E8C4", "#AE3B85", "#EA1CA9", "#FF9E6B", "#457D8B",
        "#92678B", "#00CDBB", "#9CCC04", "#002E38", "#96C57F", "#CFF6B4", "#492818", "#766E52",
        "#20370E", "#E3D19F", "#2E3C30", "#B2EACE", "#F3BDA4", "#A24E3D", "#976FD9", "#8C9FA8",
        "#7C2B73", "#4E5F37", "#5D5462", "#90956F", "#6AA776", "#DBCBF6", "#DA71FF", "#987C95",
        "#52323C", "#BB3C42", "#584D39", "#4FC15F", "#A2B9C1", "#79DB21", "#1D5958", "#BD744E",
        "#160B00", "#20221A", "#6B8295", "#00E0E4", "#102401", "#1B782A", "#DAA9B5", "#B0415D",
        "#859253", "#97A094", "#06E3C4", "#47688C", "#7C6755", "#075C00", "#7560D5", "#7D9F00",
        "#C36D96", "#4D913E", "#5F4276", "#FCE4C8", "#303052", "#4F381B", "#E5A532", "#706690",
        "#AA9A92", "#237363", "#73013E", "#FF9079", "#A79A74", "#029BDB", "#FF0169", "#C7D2E7",
        "#CA8869", "#80FFCD", "#BB1F69", "#90B0AB", "#7D74A9", "#FCC7DB", "#99375B", "#00AB4D",
        "#ABAED1", "#BE9D91", "#E6E5A7", "#332C22", "#DD587B", "#F5FFF7", "#5D3033", "#6D3800",
        "#FF0020", "#B57BB3", "#D7FFE6", "#C535A9", "#260009", "#6A8781", "#A8ABB4", "#D45262",
        "#794B61", "#4621B2", "#8DA4DB", "#C7C890", "#6FE9AD", "#A243A7", "#B2B081", "#181B00",
        "#286154", "#4CA43B", "#6A9573", "#A8441D", "#5C727B", "#738671", "#D0CFCB", "#897B77",
        "#1F3F22", "#4145A7", "#DA9894", "#A1757A", "#63243C", "#ADAAFF", "#00CDE2", "#DDBC62",
        "#698EB1", "#208462", "#00B7E0", "#614A44", "#9BBB57", "#7A5C54", "#857A50", "#766B7E",
        "#014833", "#FF8347", "#7A8EBA", "#274740", "#946444", "#EBD8E6", "#646241", "#373917",
        "#6AD450", "#81817B", "#D499E3", "#979440", "#011A12", "#526554", "#B5885C", "#A499A5",
        "#03AD89", "#B3008B", "#E3C4B5", "#96531F", "#867175", "#74569E", "#617D9F", "#E70452",
        "#067EAF", "#A697B6", "#B787A8", "#9CFF93", "#311D19", "#3A9459", "#6E746E", "#B0C5AE",
        "#84EDF7", "#ED3488", "#754C78", "#384644", "#C7847B", "#00B6C5", "#7FA670", "#C1AF9E",
        "#2A7FFF", "#72A58C", "#FFC07F", "#9DEBDD", "#D97C8E", "#7E7C93", "#62E674", "#B5639E",
        "#FFA861", "#C2A580", "#8D9C83", "#B70546", "#372B2E", "#0098FF", "#985975", "#20204C",
        "#FF6C60", "#445083", "#8502AA", "#72361F", "#9676A3", "#484449", "#CED6C2", "#3B164A",
        "#CCA763", "#2C7F77", "#02227B", "#A37E6F", "#CDE6DC", "#CDFFFB", "#BE811A", "#F77183",
        "#EDE6E2", "#CDC6B4", "#FFE09E", "#3A7271", "#FF7B59", "#4E4E01", "#4AC684", "#8BC891",
        "#BC8A96", "#CF6353", "#DCDE5C", "#5EAADD", "#F6A0AD", "#E269AA", "#A3DAE4", "#436E83",
        "#002E17", "#ECFBFF", "#A1C2B6", "#50003F", "#71695B", "#67C4BB", "#536EFF", "#5D5A48",
        "#890039", "#969381", "#371521", "#5E4665", "#AA62C3", "#8D6F81", "#2C6135", "#410601",
        "#564620", "#E69034", "#6DA6BD", "#E58E56", "#E3A68B", "#48B176", "#D27D67", "#B5B268",
        "#7F8427", "#FF84E6", "#435740", "#EAE408", "#F4F5FF", "#325800", "#4B6BA5", "#ADCEFF",
        "#9B8ACC", "#885138", "#5875C1", "#7E7311", "#FEA5CA", "#9F8B5B", "#A55B54", "#89006A",
        "#AF756F", "#2A2000", "#576E4A", "#7F9EFF", "#7499A1", "#FFB550", "#00011E", "#D1511C",
        "#688151", "#BC908A", "#78C8EB", "#8502FF", "#483D30", "#C42221", "#5EA7FF", "#785715",
        "#0CEA91", "#FFFAED", "#B3AF9D", "#3E3D52", "#5A9BC2", "#9C2F90", "#8D5700", "#ADD79C",
        "#00768B", "#337D00", "#C59700", "#3156DC", "#944575", "#ECFFDC", "#D24CB2", "#97703C",
        "#4C257F", "#9E0366", "#88FFEC", "#B56481", "#396D2B", "#56735F", "#988376", "#9BB195",
        "#A9795C", "#E4C5D3", "#9F4F67", "#1E2B39", "#664327", "#AFCE78", "#322EDF", "#86B487",
        "#C23000", "#ABE86B", "#96656D", "#250E35", "#A60019", "#0080CF", "#CAEFFF", "#323F61",
        "#A449DC", "#6A9D3B", "#FF5AE4", "#636A01", "#D16CDA", "#736060", "#FFBAAD", "#D369B4",
        "#FFDED6", "#6C6D74", "#927D5E", "#845D70", "#5B62C1", "#2F4A36", "#E45F35", "#FF3B53",
        "#AC84DD", "#762988", "#70EC98", "#408543", "#2C3533", "#2E182D", "#323925", "#19181B",
        "#2F2E2C", "#023C32", "#9B9EE2", "#58AFAD", "#5C424D", "#7AC5A6", "#685D75", "#B9BCBD",
        "#834357", "#1A7B42", "#2E57AA", "#E55199", "#316E47", "#CD00C5", "#6A004D", "#7FBBEC",
        "#F35691", "#D7C54A", "#62ACB7", "#CBA1BC", "#A28A9A", "#6C3F3B", "#FFE47D", "#DCBAE3",
        "#5F816D", "#3A404A", "#7DBF32", "#E6ECDC", "#852C19", "#285366", "#B8CB9C", "#0E0D00",
        "#4B5D56", "#6B543F", "#E27172", "#0568EC", "#2EB500", "#D21656", "#EFAFFF", "#682021",
        "#2D2011", "#DA4CFF", "#70968E", "#FF7B7D", "#4A1930", "#E8C282", "#E7DBBC", "#A68486",
        "#1F263C", "#36574E", "#52CE79", "#ADAAA9", "#8A9F45", "#6542D2", "#00FB8C", "#5D697B",
        "#CCD27F", "#94A5A1", "#790229", "#E383E6", "#7EA4C1", "#4E4452", "#4B2C00", "#620B70",
        "#314C1E", "#874AA6", "#E30091", "#66460A", "#EB9A8B", "#EAC3A3", "#98EAB3", "#AB9180",
        "#B8552F", "#1A2B2F", "#94DDC5", "#9D8C76", "#9C8333", "#94A9C9", "#392935", "#8C675E",
        "#CCE93A", "#917100", "#01400B", "#449896", "#1CA370", "#E08DA7", "#8B4A4E", "#667776",
        "#4692AD", "#67BDA8", "#69255C", "#D3BFFF", "#4A5132", "#7E9285", "#77733C", "#E7A0CC",
        "#51A288", "#2C656A", "#4D5C5E", "#C9403A", "#DDD7F3", "#005844", "#B4A200", "#488F69",
        "#858182", "#D4E9B9", "#3D7397", "#CAE8CE", "#D60034", "#AA6746", "#9E5585", "#BA6200"
    };
person Tatarize    schedule 01.09.2012
comment
ИМХО намного лучше принятого ответа. И +1 за наглядные примеры и заранее рассчитанные списки! - person Griddo; 08.04.2014
comment
Я также провел исчерпывающий поиск, чтобы максимизировать CIEDE2000 между добавленным цветом и цветами, которые уже есть в наборе, с черным и белым в качестве предопределенных цветов. Как и вы, я рано получаю два оттенка кожи: # ff9d25 (имеет тенденцию к оранжевому) и # ffb46c (имеет тенденцию к розовому). Я думаю, они очень похожи, так что, возможно, CIEDE2000 не так хорош для измерения разницы в цвете. Хотя на данный момент нет ничего лучше. Заманчиво начать проводить свои собственные эксперименты с заметными различиями, возможно, сначала с сеткой sRGB 16x16x16 ... - person Olli Niemitalo; 21.03.2016
comment
Я поднялся до 1024, но это заняло у меня больше месяца. Вы можете в равной степени использовать это с другими наборами цветов, у меня их много, варьируя цветовую гамму. И действительно CIEDE2000 на самом деле лучший. Одно из исправлений в dE2k - это цвет кожи, он выглядит для нас по-другому и имеет большее значение для многих функций. В стандартном dE они более разные, чем они должны быть на самом деле. А абрикосовый и тускло-желтый выглядят довольно непохоже. godsnotwheregodsnot.blogspot.com/2012/09/ - person Tatarize; 22.03.2016
comment
Единственное серьезное улучшение, которое я заметил, - это статические списки. Поиск цвета, наиболее удаленного от всех других цветов, на самом деле может быть не оптимальным, если вам нужно ровно 20 цветов. Вы могли бы получить лучшие результаты, если бы выполнили кластеризацию и нашли 20 цветов, для которых цветовое расстояние между всеми цветами в наборе максимально. Это может фактически превратиться в коммивояжера, и перебор (2 ^ 24) ^ 20 с помощью очень дорогостоящего алгоритма цветового расстояния может занять много времени. Однако хороший алгоритм кластеризации может быстро дать хороший результат. - person Tatarize; 22.03.2016
comment
Хорошая работа @Tatarize. Если вы все еще здесь, вы бы разместили 1024 цвета или обновили ссылку на BlogSpot? - person Robert Lugg; 26.08.2016
comment
@RobertLugg Я могу полностью возобновить работу с заданной точки, но мне удалось получить 1024-й цвет, и он был введен в изображения, которые создавала программа, поэтому у меня есть изображение грубой силы для него. Но почему-то я потерял текстовый журнал, который он создавал одинаково, и поэтому не записал цвета 1023 и 1024. У меня всего 1022 цвета. Пока я размышлял о том, чтобы исправить это и перезапустить программу. если мне не изменяет память, это примерно день работы для каждого нового цвета в этот момент. - person Tatarize; 26.08.2016
comment
На самом деле, при осмотре я мог бы даже не сделать этого для последних двух на опубликованном графике. Он создавал это и каждый раз создавал новый образ. Но на тот момент это был сплошной длинный отрезок времени для каждого нового цвета. И полное понимание того, что они бесполезны. - person Tatarize; 26.08.2016

Я разместил в Интернете страницу для процедурной генерации визуально отличных цветов:
http://phrogz.net/css/distinct-colors.html.

В отличие от других ответов здесь, которые равномерно переходят в пространство RGB или HSV (где есть нелинейная связь между значениями оси и воспринимаемым различия), моя страница использует стандартный CMI (I: c) алгоритм цветового расстояния, чтобы два цвета не были визуально слишком близки.

Последняя вкладка страницы позволяет вам сортировать значения несколькими способами, а затем чередовать их (упорядоченное перемешивание), чтобы вы получили очень четкие цвета, расположенные рядом друг с другом.

На момент написания этой статьи он хорошо работает только в Chrome и Safari с прокладкой для Firefox; в интерфейсе используются ползунки ввода диапазона HTML5, которые IE9 и Firefox пока не поддерживают изначально.

person Phrogz    schedule 22.02.2012
comment
Это отличный инструмент, спасибо за его создание. Я использовал его для создания 145 различных цветов, и я очень доволен результатами, полученными с помощью вашего инструмента различных цветов. - person Malachy; 07.05.2014
comment
Идея звучит неплохо, но я не понимаю, как работает интерфейс. Скажем, я хочу создать 64 цвета в пространстве L a b, какой параметр мне следует использовать? Я не могу получить больше 50 цветов. - person wip; 06.06.2016
comment
@wil При настройках по умолчанию на странице «Лаборатория» вы можете выбрать из 480 цветов. Когда вы переходите на вкладку «Уточнить», настройте порог, чтобы увидеть больше или меньше образцов. - person Phrogz; 06.06.2016
comment
Тем не менее, с 36 цветами я все еще получаю несколько очень похожих цветов. - person Nemo; 25.11.2017

Я думаю, что пространство HSV (или HSL) имеет здесь больше возможностей. Если вы не возражаете против дополнительного преобразования, довольно легко просмотреть все цвета, просто повернув значение Hue. Если этого недостаточно, вы можете изменить значения Saturation / Value / Lightness и снова выполнить вращение. Или вы всегда можете сместить значения оттенка или изменить свой «шаговый» угол и повернуть больше раз.

person aib    schedule 21.11.2008
comment
Однако обратите внимание, что даже равномерное изменение оттенка дает неидеальное разделение восприятия. - person Phrogz; 07.05.2014

В предыдущих решениях RGB есть изъян. Они не используют все цветовое пространство, поскольку используют значение цвета и 0 для каналов:

#006600
#330000
#FF00FF

Вместо этого они должны использовать все возможные значения цвета для создания смешанных цветов, которые могут иметь до 3 различных значений по цветовым каналам:

#336600
#FF0066
#33FF66

Используя полное цветовое пространство, вы можете создавать более четкие цвета. Например, если у вас есть 4 значения на канал, то можно сгенерировать 4 * 4 * 4 = 64 цвета. По другой схеме можно создать только 4 * 7 + 1 = 29 цветов.

Если вы хотите N цветов, то необходимое количество значений для каждого канала: ceil (cube_root (N))

После этого вы можете определить возможные значения (диапазон 0-255) (python):

max = 255
segs = int(num**(Decimal("1.0")/3))
step = int(max/segs)
p = [(i*step) for i in xrange(segs)]
values = [max]
values.extend(p)

Затем вы можете перебирать цвета RGB (это не рекомендуется):

total = 0
for red in values:
  for green in values:
    for blue in values:
      if total <= N:
        print color(red, green, blue)
      total += 1

Вложенные циклы будут работать, но не рекомендуются, так как они будут отдавать предпочтение синему каналу, а в результирующих цветах не будет достаточно красного (N, скорее всего, будет меньше, чем количество всех возможных значений цвета).

Вы можете создать лучший алгоритм для циклов, в котором каждый канал обрабатывается одинаково, а более четкие цветовые значения предпочтительнее небольших.

У меня есть решение, но я не хотел его публиковать, поскольку оно не является простым для понимания и неэффективным. Но вы можете просмотреть решение, если действительно хотите .

Вот образец из 64 созданных цветов: 64 цвета

person deancutlet    schedule 17.09.2011

Мне нужна была та же функциональность, но в простой форме.

Мне нужно было создать как можно более уникальные цвета на основе увеличивающегося значения индекса.

Вот код на C # (реализация на любом другом языке должна быть очень похожей)

Механизм очень простой

  1. Шаблон color_writers генерируется из значений indexA от 0 до 7.

  2. Для индексов ‹8 эти цвета = color_writer [indexA] * 255.

  3. Для индексов от 8 до 15 эти цвета: = color_writer [indexA] * 255 + (color_writer [indexA + 1]) * 127.

  4. Для индексов от 16 до 23 эти цвета: = color_writer [indexA] * 255 + (color_writer [indexA + 1]) * 127 + (color_writer [indexA + 2]) * 63.

И так далее:

Rand Color Generator

    private System.Drawing.Color GetRandColor(int index)
    {
        byte red = 0;
        byte green = 0;
        byte blue = 0;

        for (int t = 0; t <= index / 8; t++)
        {
            int index_a = (index+t) % 8;
            int index_b = index_a / 2;

            //Color writers, take on values of 0 and 1
            int color_red = index_a % 2;
            int color_blue = index_b % 2;
            int color_green = ((index_b + 1) % 3) % 2;

            int add = 255 / (t + 1);

            red = (byte)(red+color_red * add);
            green = (byte)(green + color_green * add);
            blue = (byte)(blue + color_blue * add);
        }

        Color color = Color.FromArgb(red, green, blue);
        return color;
    }

Примечание. Чтобы избежать создания ярких и трудноразличимых цветов (в этом примере: желтый на белом фоне), вы можете изменить его с помощью рекурсивного цикла:

    int skip_index = 0;
    private System.Drawing.Color GetRandColor(int index)
    {
        index += skip_index;
        byte red = 0;
        byte green = 0;
        byte blue = 0;

        for (int t = 0; t <= index / 8; t++)
        {
            int index_a = (index+t) % 8;
            int index_b = index_a / 2;

            //Color writers, take on values of 0 and 1
            int color_red = index_a % 2;
            int color_blue = index_b % 2;
            int color_green = ((index_b + 1) % 3) % 2;

            int add = 255 / (t + 1);

            red = (byte)(red + color_red * add);
            green = (byte)(green + color_green * add);
            blue = (byte)(blue + color_blue * add);
        }

        if(red > 200 && green > 200)
        {
            skip_index++;
            return GetRandColor(index);
        }

        Color color = Color.FromArgb(red, green, blue);
        return color;
    }
person Mich    schedule 28.06.2016

Я бы начал с установленной яркости 100% и сначала обошел бы основные цвета:

FF0000, 00FF00, 0000FF

затем комбинации

FFFF00, FF00FF, 00FFFF

затем, например, уменьшите яркость вдвое и сделайте то же самое круглое. По-настоящему четко различимых цветов не так много, после этого я бы начал изменять ширину линии и делать пунктирные / штриховые линии и т. Д.

person mmiika    schedule 21.11.2008
comment
+1 за отличное предложение использовать разные стили линий вместо цветов. - person Iiridayn; 15.08.2012

Я реализовал этот алгоритм короче

void ColorValue::SetColorValue( double r, double g, double b, ColorType myType )
{
   this->c[0] = r;
   this->c[1] = g;
   this->c[2] = b;

   this->type = myType;
}


DistinctColorGenerator::DistinctColorGenerator()
{
   mFactor = 255;
   mColorsGenerated = 0;
   mpColorCycle = new ColorValue[6];
   mpColorCycle[0].SetColorValue( 1.0, 0.0, 0.0, TYPE_RGB);
   mpColorCycle[1].SetColorValue( 0.0, 1.0, 0.0, TYPE_RGB);
   mpColorCycle[2].SetColorValue( 0.0, 0.0, 1.0, TYPE_RGB);
   mpColorCycle[3].SetColorValue( 1.0, 1.0, 0.0, TYPE_RGB);
   mpColorCycle[4].SetColorValue( 1.0, 0.0, 1.0, TYPE_RGB);
   mpColorCycle[5].SetColorValue( 0.0, 1.0, 1.0, TYPE_RGB);
}

//----------------------------------------------------------

ColorValue DistinctColorGenerator::GenerateNewColor()
{
   int innerCycleNr = mColorsGenerated % 6;
   int outerCycleNr = mColorsGenerated / 6;
   int cycleSize = pow( 2, (int)(log((double)(outerCycleNr)) / log( 2.0 ) ) );
   int insideCycleCounter = outerCycleNr % cyclesize;

   if ( outerCycleNr == 0)
   {
      mFactor = 255;
   }
   else
   {
      mFactor = ( 256 / ( 2 * cycleSize ) ) + ( insideCycleCounter * ( 256 / cycleSize ) );
   }

   ColorValue newColor = mpColorCycle[innerCycleNr] * mFactor;

   mColorsGenerated++;
   return newColor;
}
person Filip Rooms    schedule 07.10.2010

Вы также можете рассматривать цветовое пространство как все комбинации трех чисел от 0 до 255 включительно. Это представление числа от 0 до 255 ^ 3 в формате base-255, с обязательным использованием трех десятичных знаков (при необходимости добавьте нули в конец).

Итак, чтобы сгенерировать x цветов, вы должны вычислить x равномерно распределенных процентов, от 0 до 100. Получите числа, умножив эти проценты на 255 ^ 3, преобразуя эти числа в основание 255 и добавив нули, как упоминалось ранее.

Базовый алгоритм преобразования, для справки (в псевдокоде, довольно близком к C #):

int num = (number to convert);
int baseConvert = (desired base, 255 in this case);
(array of ints) nums = new (array of ints);
int x = num;
double digits = Math.Log(num, baseConvert); //or ln(num) / ln(baseConvert)
int numDigits = (digits - Math.Ceiling(digits) == 0 ? (int)(digits + 1) : (int)Math.Ceiling(digits)); //go up one if it turns out even
for (int i = 0; i < numDigits; i++)
{
  int toAdd = ((int)Math.Floor(x / Math.Pow((double)convertBase, (double)(numDigits - i - 1))));
  //Formula for 0th digit: d = num / (convertBase^(numDigits - 1))
  //Then subtract (d * convertBase^(numDigits - 1)) from the num and continue
  nums.Add(toAdd);
  x -= toAdd * (int)Math.Pow((double)convertBase, (double)(numDigits - i - 1));
}
return nums;

Возможно, вам также придется что-то сделать, чтобы немного увеличить диапазон, чтобы избежать белого и черного, если хотите. Эти числа на самом деле не являются гладкой цветовой шкалой, но они будут генерировать отдельные цвета, если у вас их не слишком много.

Этот вопрос есть больше о базовом преобразовании в .NET.

person Tom Hamming    schedule 02.12.2010

для получения n-го цвета. Просто такого кода было бы достаточно. Это я использую в своей проблеме кластеризации opencv. Это создаст разные цвета при изменении col.

for(int col=1;col<CLUSTER_COUNT+1;col++){
switch(col%6)
   {
   case 1:cout<<Scalar(0,0,(int)(255/(int)(col/6+1)))<<endl;break;
   case 2:cout<<Scalar(0,(int)(255/(int)(col/6+1)),0)<<endl;break;
    case 3:cout<<Scalar((int)(255/(int)(col/6+1)),0,0)<<endl;break;
    case 4:cout<<Scalar(0,(int)(255/(int)(col/6+1)),(int)(255/(int)(col/6+1)))<<endl;break;
    case 5:cout<<Scalar((int)(255/(int)(col/6+1)),0,(int)(255/(int)(col/6+1)))<<endl;break;
    case 0:cout<<Scalar((int)(255/(int)(col/6)),(int)(255/(int)(col/6)),0)<<endl;break;
   }
}
person sai siva sundar    schedule 02.02.2013

Если кому-то нужно сгенерировать случайный темный цвет от среднего до высокого для белого переднего плана в C #, вот код.

[DllImport("shlwapi.dll")]
public static extern int ColorHLSToRGB(int H, int L, int S);

public static string GetRandomDarkColor()
{
    int h = 0, s = 0, l = 0;
    h = (RandomObject.Next(1, 2) % 2 == 0) ? RandomObject.Next(0, 180) : iApp.RandomObject.Next(181, 360);
    s = RandomObject.Next(90, 160);
    l = RandomObject.Next(80, 130);

    return System.Drawing.ColorTranslator.FromWin32(ColorHLSToRGB(h, l, s)).ToHex();
}

private static string ToHex(this System.Drawing.Color c)
{
    return "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
}

Вы можете заменить RandomObject на свой собственный Random объект класса.

person Krish    schedule 02.07.2019

Вы можете получить случайный набор из 3 255 значений и сравнить его с последним набором из 3 значений, убедившись, что каждое из них находится как минимум на X от старых значений, прежде чем использовать их.

СТАРАЯ: 190, 120, 100

НОВИНКА: 180, 200, 30

Если X = 20, то новый набор будет регенерирован снова.

person Totty    schedule 21.11.2008
comment
Мне почти любопытно провести математические вычисления и подсчитать, сколько времени в среднем может пройти, прежде чем этот алгоритм войдет в бесконечный цикл, когда больше нет возможных решений. - person Tatarize; 25.05.2015
comment
Хм. Как ни странно, в вашем ответе говорится, что любое значение r, слишком близкое к другому значению R, вызовет регенерацию, в лучшем случае менее 12. Хотя это странно назвало бы цвета Красный и Синий слишком близкими, потому что оба имеют зеленый цвет 0, который находится в пределах 20. Я имею в виду, что буквально в вашем примере говорится: colorcodehex.com/be7864 colorcodehex.com/b4c81e. слишком близко друг к другу и должны быть регенерированы. - person Tatarize; 25.05.2015