320

多数のランダムで美しい色を生成する単純なアルゴリズムを探しています。そのため、クレイジーなネオンカラー、糞を連想させる色などはありません。

この問題の解決策を見つけましたが、それらは RGB 以外のカラー パレットに依存しています。前後にマッピングするよりも、ストレート RGB を使用するほうがよいでしょう。これらの他のソリューションも、せいぜい 32 程度の適切なランダム カラーしか生成できません。

どんなアイデアでも素晴らしいでしょう。

4

16 に答える 16

442

ランダムな色のRGB値を一定の色のRGB値と平均することができます。

(Javaの例)

public Color generateRandomColor(Color mix) {
    Random random = new Random();
    int red = random.nextInt(256);
    int green = random.nextInt(256);
    int blue = random.nextInt(256);

    // mix the color
    if (mix != null) {
        red = (red + mix.getRed()) / 2;
        green = (green + mix.getGreen()) / 2;
        blue = (blue + mix.getBlue()) / 2;
    }

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


ランダムな色を白(255、255、255)と混合すると、元の色の色相を維持しながら明度を上げることで、ニュートラルなパステルを作成します。これらのランダムに生成されたパステルは、特に多数の場合、通常はうまく調和します。

上記の方法を使用して生成されたパステルカラーは次のとおりです。

初め


ランダムな色を一定のパステルカラーと混合することもできます。これにより、中間色の色付きのセットが作成されます。たとえば、水色を使用すると、次のような色が作成されます。

2番


さらに、補色や陰影のレベルを考慮したヒューリスティックをジェネレーターに追加することもできますが、それはすべて、ランダムな色で実現したい印象によって異なります。

いくつかの追加リソース:

于 2008-09-04T06:00:39.977 に答える
89

私はカラー ホイールを使用し、黄金角 (137,5 度) を追加できるランダムな位置を指定します。

http://en.wikipedia.org/wiki/Golden_angle

重ならない毎回異なる色を得るために。

カラー ホイールの明るさを調整すると、さまざまな明るい色と暗い色の組み合わせも得られます。

黄金比を使用した問題と解決策を非常によく説明しているこのブログ投稿を見つけました。

http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/

更新:私はこの他のアプローチを見つけました:

これは RYB (red, yellow, blue) メソッドと呼ばれ、このペーパーで説明されています。

http://threekings.tk/mirror/ryb_TR.pdf

「ペイントにインスパイアされたカラー合成」として。

アルゴリズムによって色が生成され、以前に選択された色とのユークリッド距離が最大になるように新しい色が選択されます。

ここでは、JavaScript での適切な実装を見つけることができます。

http://afriggeri.github.com/RYB/

更新 2:

Sciences Po Medialb は、データ サイエンティスト向けのカラー パレットを生成する "I want Hue" というツールをリリースしました。さまざまな色空間を使用し、k-means クラスタリングまたは力ベクトル (反発グラフ) を使用してパレットを生成します。これらの方法の結果は非常に優れており、Web ページで理論と実装を示しています。

http://tools.medialab.sciences-po.fr/iwanthue/index.php

于 2011-02-15T19:01:04.720 に答える
23

JavaScript の場合:

function pastelColors(){
    var r = (Math.round(Math.random()* 127) + 127).toString(16);
    var g = (Math.round(Math.random()* 127) + 127).toString(16);
    var b = (Math.round(Math.random()* 127) + 127).toString(16);
    return '#' + r + g + b;
}

ここでアイデアを見ました:http://blog.functionalfun.net/2008/07/random-pastel-colour-generator.html

于 2012-09-04T15:05:23.603 に答える
11

別のパレットに変換することは、これを行うためのはるかに優れた方法です。彼らがそうする理由があります:他のパレットは「知覚的」です-つまり、それらは似たような色を近づけ、1つの変数を調整すると予測可能な方法で色が変わります。「うまく調和する」色の間に明らかな関係がないRGBには、そのどれも当てはまりません。

于 2009-06-07T20:45:33.690 に答える
7

TriadMixingCIE94を使用して、似たような色を避けることに成功しました。次の画像では、赤、黄、白の入力色を使用しています。ここを参照してください。

TriadMixing + CIE94

于 2016-12-09T20:15:29.700 に答える
5

シンプルで利点があるため、見逃すべきではない答えは、実際の写真や絵画のサンプリングです。現代美術の写真、セザンヌ、ゴッホ、モネ、写真のサムネイルでランダムな色を必要なだけランダムなピクセルをサンプリングします...利点は、テーマごとに色を取得できることと、それらが有機的な色であることです。20 ~ 30 枚の写真をフォルダーに入れ、毎回ランダムに写真をランダムにサンプリングするだけです。

HSV 値への変換は、心理学に基づくパレットのコード アルゴリズムとして広く普及しています。hsv はランダム化が容易です。

于 2013-08-16T08:59:14.913 に答える
3

これは、C# のクイック アンド ダーティ カラー ジェネレーターです (この記事で説明されている「RYB アプローチ」を使用)。JavaScriptからの書き直しです。

使用する:

List<Color> ColorPalette = ColorGenerator.Generate(30).ToList();

最初の 2 色は、白と黒の色合いになる傾向があります。私はしばしば次のようにスキップします (Linq を使用):

List<Color> ColorsPalette = ColorGenerator
            .Generate(30)
            .Skip(2) // skip white and black
            .ToList(); 

実装:

public static class ColorGenerator
{

    // RYB color space
    private static class RYB
    {
        private static readonly double[] White = { 1, 1, 1 };
        private static readonly double[] Red = { 1, 0, 0 };
        private static readonly double[] Yellow = { 1, 1, 0 };
        private static readonly double[] Blue = { 0.163, 0.373, 0.6 };
        private static readonly double[] Violet = { 0.5, 0, 0.5 };
        private static readonly double[] Green = { 0, 0.66, 0.2 };
        private static readonly double[] Orange = { 1, 0.5, 0 };
        private static readonly double[] Black = { 0.2, 0.094, 0.0 };

        public static double[] ToRgb(double r, double y, double b)
        {
            var rgb = new double[3];
            for (int i = 0; i < 3; i++)
            {
                rgb[i] = White[i]  * (1.0 - r) * (1.0 - b) * (1.0 - y) +
                         Red[i]    * r         * (1.0 - b) * (1.0 - y) +
                         Blue[i]   * (1.0 - r) * b         * (1.0 - y) +
                         Violet[i] * r         * b         * (1.0 - y) +
                         Yellow[i] * (1.0 - r) * (1.0 - b) *        y +
                         Orange[i] * r         * (1.0 - b) *        y +
                         Green[i]  * (1.0 - r) * b         *        y +
                         Black[i]  * r         * b         *        y;
            }

            return rgb;
        }
    }

    private class Points : IEnumerable<double[]>
    {
        private readonly int pointsCount;
        private double[] picked;
        private int pickedCount;

        private readonly List<double[]> points = new List<double[]>();

        public Points(int count)
        {
            pointsCount = count;
        }

        private void Generate()
        {
            points.Clear();
            var numBase = (int)Math.Ceiling(Math.Pow(pointsCount, 1.0 / 3.0));
            var ceil = (int)Math.Pow(numBase, 3.0);
            for (int i = 0; i < ceil; i++)
            {
                points.Add(new[]
                {
                    Math.Floor(i/(double)(numBase*numBase))/ (numBase - 1.0),
                    Math.Floor((i/(double)numBase) % numBase)/ (numBase - 1.0),
                    Math.Floor((double)(i % numBase))/ (numBase - 1.0),
                });
            }
        }

        private double Distance(double[] p1)
        {
            double distance = 0;
            for (int i = 0; i < 3; i++)
            {
                distance += Math.Pow(p1[i] - picked[i], 2.0);
            }

            return distance;
        }

        private double[] Pick()
        {
            if (picked == null)
            {
                picked = points[0];
                points.RemoveAt(0);
                pickedCount = 1;
                return picked;
            }

            var d1 = Distance(points[0]);
            int i1 = 0, i2 = 0;
            foreach (var point in points)
            {
                var d2 = Distance(point);
                if (d1 < d2)
                {
                    i1 = i2;
                    d1 = d2;
                }

                i2 += 1;
            }

            var pick = points[i1];
            points.RemoveAt(i1);

            for (int i = 0; i < 3; i++)
            {
                picked[i] = (pickedCount * picked[i] + pick[i]) / (pickedCount + 1.0);
            }

            pickedCount += 1;
            return pick;
        }

        public IEnumerator<double[]> GetEnumerator()
        {
            Generate();
            for (int i = 0; i < pointsCount; i++)
            {
                yield return Pick();
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }

    public static IEnumerable<Color> Generate(int numOfColors)
    {
        var points = new Points(numOfColors);

        foreach (var point in points)
        {
            var rgb = RYB.ToRgb(point[0], point[1], point[2]);
            yield return Color.FromArgb(
                (int)Math.Floor(255 * rgb[0]),
                (int)Math.Floor(255 * rgb[1]),
                (int)Math.Floor(255 * rgb[2]));
        }
    }
}
于 2014-01-26T09:09:40.570 に答える
2
function fnGetRandomColour(iDarkLuma, iLightLuma) 
{       
  for (var i=0;i<20;i++)
  {
    var sColour = ('ffffff' + Math.floor(Math.random() * 0xFFFFFF).toString(16)).substr(-6);

    var rgb = parseInt(sColour, 16);   // convert rrggbb to decimal
    var r = (rgb >> 16) & 0xff;  // extract red
    var g = (rgb >>  8) & 0xff;  // extract green
    var b = (rgb >>  0) & 0xff;  // extract blue

    var iLuma = 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709


    if (iLuma > iDarkLuma && iLuma < iLightLuma) return sColour;
  }
  return sColour;
} 

パステルの場合は、より高い輝度の暗い/明るい整数を渡します - すなわち fnGetRandomColour(120, 250)

クレジット: http://paulirish.com/2009/random-hex-color-code-snippets/stackoverflow.com/questions/12043187/how-to-check-if-hex-color-is-too-blackへのすべての クレジット

于 2013-02-11T10:28:12.397 に答える
1

David Crow の元の回答の JavaScript 適応、IE および Nodejs 固有のコードが含まれています。

generateRandomComplementaryColor = function(r, g, b){
    //--- JavaScript code
    var red = Math.floor((Math.random() * 256));
    var green = Math.floor((Math.random() * 256));
    var blue = Math.floor((Math.random() * 256));
    //---

    //--- Extra check for Internet Explorers, its Math.random is not random enough.
    if(!/MSIE 9/i.test(navigator.userAgent) && !/MSIE 10/i.test(navigator.userAgent) && !/rv:11.0/i.test(navigator.userAgent)){
        red = Math.floor((('0.' + window.crypto.getRandomValues(new Uint32Array(1))[0]) * 256));
        green = Math.floor((('0.' + window.crypto.getRandomValues(new Uint32Array(1))[0]) * 256));
        blue = Math.floor((('0.' + window.crypto.getRandomValues(new Uint32Array(1))[0]) * 256));
    };
    //---

    //--- nodejs code
    /*
    crypto = Npm.require('crypto');
    red = Math.floor((parseInt(crypto.randomBytes(8).toString('hex'), 16)) * 1.0e-19 * 256);
    green = Math.floor((parseInt(crypto.randomBytes(8).toString('hex'), 16)) * 1.0e-19 * 256);
    blue = Math.floor((parseInt(crypto.randomBytes(8).toString('hex'), 16)) * 1.0e-19 * 256);
    */
    //---

    red = (red + r)/2;
    green = (green + g)/2;
    blue = (blue + b)/2;

    return 'rgb(' + Math.floor(red) + ', ' + Math.floor(green) + ', ' + Math.floor(blue) + ')';
}

以下を使用して関数を実行します。

generateRandomComplementaryColor(240, 240, 240);
于 2015-07-25T17:44:38.580 に答える
0

欲しいものをアルゴリズムで得るのは難しいでしょう - 人々は長い間色彩理論を研究してきましたが、すべてのルールを知っているわけではありません.

ただし、悪い色の組み合わせを選別するために使用できるルールがいくつかあります (つまり、色の衝突や補色の選択に関するルールがあります)。

図書館のアート セクションにアクセスし、色彩理論に関する書籍を調べて、適切な色を作成する前に理解を深めることをお勧めします。なぜ特定の組み合わせが機能し、他の組み合わせが機能しないのかさえわからないようです。 t。

-アダム

于 2008-09-04T03:36:43.800 に答える
0

CG HSVtoRGB シェーダー関数を使用することを強くお勧めします。それらは素晴らしいです...これにより、おそらくないでしょう!crt モニターのようなコントロールではなく、ペインターのような自然なカラー コントロールが得られます!

これは、1 つの float 値を作成する方法です。つまり、グレー、色、明るさ、彩度などの組み合わせの 1000 ds に:

int rand = a global color randomizer that you can control by script/ by a crossfader etc.
float h = perlin(grey,23.3*rand)
float s = perlin(grey,54,4*rand)
float v = perlin(grey,12.6*rand)

Return float4 HSVtoRGB(h,s,v);

結果は素晴らしい色のランダム化です! それは自然ではありませんが、自然な色のグラデーションを使用し、有機的で制御可能な虹色/パステルのパラメーターに見えます.

パーリンの場合、この関数を使用できます。これは、パーリンの高速ジグザグ バージョンです。

function  zig ( xx : float ): float{    //lfo nz -1,1
    xx= xx+32;
    var x0 = Mathf.Floor(xx);
    var x1 = x0+1;
    var v0 = (Mathf.Sin (x0*.014686)*31718.927)%1;
    var v1 = (Mathf.Sin  (x1*.014686)*31718.927)%1;
    return Mathf.Lerp( v0 , v1 , (xx)%1 )*2-1;
}
于 2014-03-30T12:23:57.883 に答える
0

それらを特定の明るさの範囲内に収めることができます。それは「ネオン」色の量を少し制御します。たとえば、「明るさ」

brightness = sqrt(R^2+G^2+B^2)

一定の上限内にあると、色あせた明るい色になります。逆に、特定の下限内にある場合は、より暗くなります。これにより、非常に目立つ色が排除され、非常に高いまたは非常に低い境界を選択した場合、それらはすべて白または黒にかなり近くなります.

于 2008-09-04T02:16:50.263 に答える