Estetik açıdan hoş bir renk paleti oluşturmak için rastgele algoritma [kapalı]


301

Çok sayıda rastgele, estetik açıdan hoş renkler üretmek için basit bir algoritma arıyorum. Yani çılgın neon renkler, dışkı anımsatan renkler vb.

Bu soruna çözümler buldum ancak RGB'den farklı renk paletlerine güveniyorlar. Ben sadece ileri geri haritalama yerine düz RGB kullanmak istiyorum. Bu diğer çözümler aynı zamanda en fazla 32 ya da çok hoş rastgele renk üretebilir.

Herhangi bir fikir harika olurdu.


2
Her ziyaretimde rastgele renk üreten bir web sitesi yapardım. "Bu renk kayalar" / "bu renk berbat" oyu var. Sonra oy oranına göre sıralayın.
Nosredna

HSL ve HSV'yi kontrol edebilirsiniz.
Jim Keener

48
"dışkı anımsatan renkler" Bayıldım
lol

Bu bir algoritma değil.
Matt The Ninja

Soru kapandığı için bir yorum ekleyeceğim. Denemedim, ancak fraktal veya prosedürel bir yol denemek ilginç olurdu, yani Midpoint Deplasman algoritması veya varyantları ( lighthouse3d.com/opengl/terrain/index.php?mpd2 ) veya Perlin Noise kullanarak, ancak yükseklikler yerine renklerin rgb bileşenlerini karıştırmak için.
alfoks

Yanıtlar:


426

Rastgele renklerin RGB değerlerini sabit bir rengin RGB değerleriyle ortalayabilirsiniz:

(Java'da örnek)

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;
}


Rastgele renklerin beyazla (255, 255, 255) karıştırılması, orijinal rengin tonunu korurken hafifliği artırarak nötr pasteller oluşturur. Rastgele üretilen bu pasteller genellikle, özellikle çok sayıda, birlikte iyi gider.

Yukarıdaki yöntem kullanılarak oluşturulan bazı pastel renkler şunlardır:

İlk


Rastgele rengi, nötr renklerin renkli bir setiyle sonuçlanan sabit bir pastel ile de karıştırabilirsiniz. Örneğin, açık mavi kullanmak aşağıdaki gibi renkler oluşturur:

İkinci


Daha ileriye, tamamlayıcı renkleri veya gölgeleme seviyelerini dikkate alan jeneratörünüze sezgisel tarama ekleyebilirsiniz, ancak hepsi rastgele renklerinizle elde etmek istediğiniz izlenime bağlıdır.

Bazı ek kaynaklar:


3
Tek uyarı ayırt edilebilirliğin kaybı gibi görünüyor. Beyaz gibi bir renkle ortalama kırmızı yeşil ve mavi alarak, doğal olarak tüm renkler beyaza yaklaşır ve aralarındaki farkları azaltır. Örneğin, ilk ekran görüntüsüne bakarsanız: Bu yeşillikler yan yana olduğunda, kesinlikle onları ayırt edebilirim, ancak üretilen bazı grafiklerde bitişik değilse ne olur? Sorunlu olabilir.
Zelphir Kaltstahl

Rastgele renk bileşeni oluştururken, üst sınırı 200 gibi daha az bir şeyle kısıtlamayı deneyin.
Nickolodeon

87

Bir renk tekerleği kullanırdım ve rastgele bir konum verildiğinde altın açıyı (137,5 derece)

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

her seferinde örtüşmeyen farklı renkler elde etmek için.

Renk tekerleğinin parlaklığını ayarlayarak farklı parlak / koyu renk kombinasyonları da alabilirsiniz.

Sorunu ve altın oranı kullanarak çözümü gerçekten iyi açıklayan bu blog gönderisini buldum.

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

GÜNCELLEME: Bu başka yaklaşımı buldum:

Buna RYB (kırmızı, sarı, mavi) yöntemi denir ve bu makalede açıklanmıştır:

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

"Boyadan Esinlenilmiş Renk Birleştirme".

Algoritma renkleri üretir ve her yeni renk, önceden seçilenlere öklid mesafesini en üst düzeye çıkarmak için seçilir.

Javascript'te iyi bir uygulama bulabilirsiniz:

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

GÜNCELLEME 2:

Sciences Po Medialb, veri bilimcileri için renk paletleri oluşturan "I Hue'yu istiyorum" adlı bir araç yayınladı. Farklı renk uzayları kullanmak ve k-araçları kümeleme veya kuvvet vektörleri (itme grafikleri) kullanarak paletler oluşturmak Bu yöntemlerden elde edilen sonuçlar çok iyidir, teoriyi ve web sayfalarında bir uygulamayı gösterirler.

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


Cevap iWantHue. Oraya git. Hayret edin.
Irongaze.com

23

Javascript dilinde:

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;
}

Fikri burada gördüm: http://blog.functionalfun.net/2008/07/random-pastel-colour-generator.html


Tamamen doğru değil: tek basamaklı sayılar için de sıfır doldurmaya ihtiyacınız var ... Her neyse, işte arayanlar için çalışan bir keman: jsfiddle.net/RedDevil/LLYBQ ----- Scratch ... Yapmadım +127 bitine dikkat edin ... Ama o zaman bu koyu gölgeler oluşturmaz.
kumarharsh

2
Orijinal fikir keyfi olarak hoş renkler yaratmaktı. Koyu tonlar benim için hoş görünmüyor;)
motobói

11

Başka bir palete dönüştürmek bunu yapmanın çok daha üstün bir yoludur. Bunun bir nedeni var: diğer paletler 'algısal' - yani benzer görünen renkleri birbirine yakın koyuyorlar ve bir değişkeni ayarlamak rengi tahmin edilebilir bir şekilde değiştiriyor. Bunların hiçbiri, renkler arasında “birlikte iyi giden” belirgin bir ilişkinin olmadığı RGB için geçerli değildir.


6

Benzer renkleri önlemek için TriadMixing ve CIE94 kullanarak başarılı oldum . Aşağıdaki resimde kırmızı, sarı ve beyaz giriş renkleri kullanılmıştır. Buraya bakın .

TriadMixing + CIE94


5

Göz ardı edilmemesi gereken bir cevap, çünkü basittir ve avantajlar sunar, gerçek hayat fotoğraflarının ve resimlerinin örneklemesidir. Modern sanat resimlerinin, cezanne, van gogh, monnet, fotoğrafların küçük resimlerinde rastgele renkler istediğiniz kadar rastgele piksel örnekleyin ... avantajı, temalara göre renk alabilmeniz ve organik renkler olmasıdır. sadece bir klasöre 20-30 resim koyun ve rastgele örnek her zaman rastgele bir resim.

HSV değerlerine dönüşüm, psikolojik temelli palet için yaygın bir kod algoritmasıdır. hsv'nin randomize edilmesi daha kolaydır.


1
mkweb.bcgsc.ca/color_summarizer/?analyze İşte gerçek hayattaki fotoğrafları analiz edebilen ve size geri dönebilen çevrimiçi bir araç. RGB değerlerinin Grapher, gerçek hayattaki fotoğrafların grafiklerinde neler olduğunu hissedebileceğini söylüyor .... rasgele
renkler

4

Php olarak:

function pastelColors() {
    $r = dechex(round(((float) rand() / (float) getrandmax()) * 127) + 127);
    $g = dechex(round(((float) rand() / (float) getrandmax()) * 127) + 127);
    $b = dechex(round(((float) rand() / (float) getrandmax()) * 127) + 127);

    return "#" . $r . $g . $b;
}

Kaynak: https://stackoverflow.com/a/12266311/2875783


3

İşte C # hızlı ve kirli renk üreticisi (bu makalede açıklanan 'RYB yaklaşımı' kullanarak ). JavaScript'ten yeniden yazma .

kullanın:

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

İlk iki renk beyaz ve siyah bir tonda olma eğilimindedir. Ben sık sık bunları (Linq kullanarak) atla:

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

Uygulama:

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]));
        }
    }
}

Java yanıtını kaldırdım, ancak gerekirse, Java sürümü şu Gist'te
Dylan Watson

3

David Crow'un R iki astarlı yöntemi:

GetRandomColours <- function(num.of.colours, color.to.mix=c(1,1,1)) {
  return(rgb((matrix(runif(num.of.colours*3), nrow=num.of.colours)*color.to.mix)/2))
}

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;
} 

Pastel için, daha yüksek luma koyu / açık tam sayılarını geçirin - yani fnGetRandomColour (120, 250)

Kredi: http://paulirish.com/2009/random-hex-color-code-snippets/ stackoverflow.com/questions/12043187/how-to-check-if-hex-color-is-too-black


1

David Crow'un orijinal cevabı, IE ve Nodejs'e özgü kodun JavaScript uyarlaması dahil.

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) + ')';
}

İşlevi kullanarak şunları çalıştırın:

generateRandomComplementaryColor(240, 240, 240);

1

Farklı renkler kullanın .

Javascript ile yazılmıştır.

Görsel olarak bir palet oluşturur farklı renklerden .

farklı renkler son derece yapılandırılabilir:

  • Palette kaç renk olduğunu seçin
  • Tonu belirli bir aralıkla kısıtla
  • Chroma'yı (doygunluk) belirli bir aralıkla kısıtlayın
  • Hafifliği belirli bir aralıkla kısıtlayın
  • Paletin genel kalitesini yapılandırma

0

belli bir parlaklık içinde olabilirsiniz. "neon" renklerin miktarını biraz kontrol ederdi. örneğin, "parlaklık"

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

belli bir yüksek sınır içindeydi, solgun, açık bir rengi olurdu. Tersine, eğer belirli bir düşük sınır içinde olsaydı, daha karanlık olurdu. Bu, herhangi bir çılgın, çarpıcı renkleri ortadan kaldıracak ve gerçekten yüksek veya gerçekten düşük bir sınır seçerseniz, bunların hepsi beyaz veya siyaha oldukça yakın olacaktır.


0

İstediğiniz şeyi algoritmik olarak elde etmek zor olacak - insanlar renk teorisini uzun zamandır çalışıyorlar ve tüm kuralları bile bilmiyorlar.

Bununla birlikte, kötü renk kombinasyonlarını kaldırmak için kullanabileceğiniz bazı kurallar vardır (yani, renkleri çakışmak ve tamamlayıcı renkleri seçmek için kurallar vardır).

Bir tane yapmaya çalışmadan önce iyi bir rengin ne olduğunu daha iyi anlamak için kütüphanenizin sanat bölümünü ziyaret etmenizi ve renk teorisi ile ilgili kitaplara göz atmanızı öneririm. t.

-Adam


0

CG HSVtoRGB gölgelendirici işlevini kullanmanızı şiddetle tavsiye ederim, harikalar ... muhtemelen size göre bir crt monitör gibi kontrol yerine ressam gibi doğal renk kontrolü sağlıyor!

Bu 1 kayan değer yapmanın bir yoludur. yani Gri, 1000 ds renk ve parlaklık ve doygunluk vb kombinasyonlarına:

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);

sonuç MUHTEŞEM RENK RANDOMİZASYONU! doğal değil ama doğal renk gradyanları kullanıyor ve organik ve kontrol edilebilir yanardöner / pastel parametreleri görünüyor.

Perlin için bu işlevi kullanabilirsiniz, perlin'in hızlı zig zag sürümüdür.

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;
}

0

İşte yaptığım bir site için yazdığım bir şey. Sınıfla herhangi bir div için otomatik olarak rastgele düz bir arka plan rengi oluşturur .flat-color-gen. Jquery yalnızca sayfaya css eklemek için gereklidir; bunun ana parçası olan generateFlatColorWithOrder()yöntem değildir.

JsFiddle Bağlantısı

(function($) {
    function generateFlatColorWithOrder(num, rr, rg, rb) {
        var colorBase = 256;
        var red = 0;
        var green = 0;
        var blue = 0;
        num = Math.round(num);
        num = num + 1;
        if (num != null) {

            red = (num*rr) % 256;
            green = (num*rg) % 256;
            blue = (num*rb) % 256;
        }
        var redString = Math.round((red + colorBase) / 2).toString();
        var greenString = Math.round((green + colorBase) / 2).toString();
        var blueString = Math.round((blue + colorBase) / 2).toString();
        return "rgb("+redString+", "+greenString+", "+blueString+")";
        //return '#' + redString + greenString + blueString;
    }

    function generateRandomFlatColor() {
        return generateFlatColorWithOrder(Math.round(Math.random()*127));
    }

    var rr = Math.round(Math.random()*1000);
    var rg = Math.round(Math.random()*1000);
    var rb = Math.round(Math.random()*1000);
    console.log("random red: "+ rr);
    console.log("random green: "+ rg);
    console.log("random blue: "+ rb);
    console.log("----------------------------------------------------");
    $('.flat-color-gen').each(function(i, obj) {
        console.log(generateFlatColorWithOrder(i));
        $(this).css("background-color",generateFlatColorWithOrder(i, rr, rg, rb).toString());
    });
})(window.jQuery);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.