미적으로 유쾌한 색상 팔레트를 임의로 생성하는 알고리즘 [닫기]


301

나는 많은 수의 임의의 미적으로 유쾌한 색상을 생성하는 간단한 알고리즘을 찾고 있습니다. 따라서 미친 네온 색, 대변을 연상시키는 색 등이 없습니다.

이 문제에 대한 해결책을 찾았지만 RGB보다 대체 색상 팔레트에 의존합니다. 오히려 앞뒤로 매핑하는 것보다 직선 RGB를 사용하고 싶습니다. 이러한 다른 솔루션은 최대 32 개 정도의 임의 색상 만 생성 할 수 있습니다.

어떤 아이디어라도 좋을 것입니다.


2
방문 할 때마다 임의의 색상을 생성하는 웹 사이트를 만들었습니다. "이 색이 흔들린다"/ "이 색이 빠진다"투표하십시오. 그런 다음 투표 비율로 정렬하십시오.
Nosredna 2016

HSL과 HSV를 확인할 수 있습니다.
Jim Keener

48
"배설물을 연상시키는 색"나는 그것을 좋아한다
lol

알고리즘이 아닙니다.
매트 닌자

질문이 마감되었으므로 의견을 추가하겠습니다. 나는 그것을 시도하지는 않았지만 Midpoint Displacement 알고리즘 또는 변형 ( lighthouse3d.com/opengl/terrain/index.php?mpd2 ) 또는 Perlin Noise를 사용하지만 프랙탈 대신 절차 또는 방법으로 시도하는 것이 흥미로울 것입니다. 색상의 RGB 구성 요소를 혼합합니다.
alfoks

답변:


426

임의 색상의 RGB 값을 일정한 색상의 RGB 값으로 평균화 할 수 있습니다.

(자바의 예)

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)과 혼합하면 원래 색상의 색조를 유지하면서 명도를 높여서 중립 파스텔을 만듭니다. 이 무작위로 생성 된 파스텔은 일반적으로 특히 많은 수에서 잘 어울립니다.

위의 방법을 사용하여 생성 된 일부 파스텔 색상은 다음과 같습니다.

먼저


임의의 색상을 일정한 파스텔과 혼합하여 색조가 중간색으로 설정 될 수 있습니다. 예를 들어 하늘색을 사용하면 다음과 같은 색상이 생성됩니다.

둘째


또한 보완적인 색상이나 음영 수준을 고려하여 생성기에 휴리스틱을 추가 할 수 있지만, 모든 색상은 임의의 색상으로 달성하려는 인상에 따라 달라집니다.

몇 가지 추가 자료 :


3
유일한 경고는 구별의 상실 인 것 같습니다. 흰색과 같은 하나의 색상으로 빨강 녹색과 파랑의 평균을 취하면 자연스럽게 모든 색상이 흰색에 가까워지고 그 차이가 줄어 듭니다. 예를 들어 첫 번째 스크린 샷을 보면 : 녹색이 서로 옆에있을 때 확실히 구별 할 수 있지만 일부 그래픽에서 인접하지 않으면 어떻게됩니까? 문제가 될 수 있습니다.
Zelphir Kaltstahl

임의의 색상 구성 요소를 생성 할 때 상한을 200과 같이 더 적은 것으로 제한하십시오.
Nickolodeon

87

나는 컬러 휠을 사용하고 임의의 위치에 황금 각도 (137,5도)를 추가 할 수 있습니다

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

겹치지 않을 때마다 다른 색상을 얻기 위해.

컬러 휠의 밝기를 조정하면 다른 밝고 어두운 색상 조합을 얻을 수 있습니다.

황금 비율을 사용하는 문제와 해결책을 잘 설명하는이 블로그 게시물을 찾았습니다.

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

업데이트 : 방금이 다른 접근법을 찾았습니다.

RYB (빨강, 노랑, 파랑) 방법이라고하며이 백서에 설명되어 있습니다.

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

"페인트 영감 색상 합성"으로.

알고리즘은 색상을 생성하고 각각의 새로운 색상은 이전에 선택한 색상과의 유클리드 거리를 최대화하도록 선택됩니다.

다음은 자바 스크립트에서 좋은 구현을 찾을 수 있습니다.

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

업데이트 2 :

Sciences Po Medialb는 데이터 과학자를위한 컬러 팔레트를 생성하는 "I want Hue"라는 도구를 출시했습니다. k- 평균 군집화 또는 힘 벡터 (반발 그래프)를 사용하여 다른 색상 공간 사용 및 팔레트 생성 이러한 방법의 결과는 매우 좋으며 웹 페이지에 이론과 구현을 보여줍니다.

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


iWantHue가 답입니다. 저기로가. 놀랍다.
Irongaze.com

23

자바 스크립트에서 :

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


완전히 정확하지는 않습니다 : 한 자릿수 숫자도 0으로 채워야합니다 ... 어쨌든, 여기에는 찾는 사람들을위한 바이올린이 있습니다 : jsfiddle.net/RedDevil/LLYBQ ----- 스크래치 ... 나는하지 않았다 +127 비트를 주목하십시오 ... 그러나 이것은 어두운 색조를 생성하지 않습니다.
kumarharsh

2
원래 아이디어는 임의로 유쾌한 색상을 생성하는 것이 었습니다. 어두운 그늘은 나에게 쾌적 해 보이지 않는다;)
motobói

11

다른 팔레트로 변환하는 것이 훨씬 뛰어난 방법입니다. 그 이유는 다음과 같습니다. 다른 팔레트는 '지각 적'입니다. 즉, 비슷한 모양의 색상을 가깝게 배치하고 하나의 변수를 조정하면 예측 가능한 방식으로 색상이 변경됩니다. RGB에는 "모두 잘 어울리는"색상 사이에 명확한 관계가없는 것은 사실이 아닙니다.



5

간과해서는 안되는 대답은 간단하고 장점이 있기 때문에 실제 사진과 그림을 샘플링하는 것입니다. 현대 미술 사진, cezanne, van gogh, monnet, 사진의 썸네일에서 임의의 색상을 원하는만큼 임의의 픽셀을 샘플링하십시오. 장점은 테마별로 색상을 얻을 수 있고 유기 색상이라는 것입니다. 폴더에 20-30 장의 사진을 넣고 매번 임의의 그림을 무작위로 샘플링하십시오.

HSV 값으로의 변환은 심리적 기반 팔레트를위한 광범위한 코드 알고리즘입니다. hsv는 무작위 화하기가 더 쉽습니다.


1
mkweb.bcgsc.ca/color_summarizer/?analyze 실제 사진을 분석하고 사용자에게 반환 할 수있는 온라인 도구는 RGB 값의 그래퍼가 실제 사진이 그래프에 어떤 느낌을 줄 수 있다고 말합니다 .... 임의 색상에 대한 전위 알고리즘을 설계하려는 경우 매우 유용한 웹 사이트
com.prehensible

4

PHP에서 :

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

출처 : https://stackoverflow.com/a/12266311/2875783


3

다음은 C #에서 빠르고 더러운 색상 생성기입니다 (이 기사에 설명 된 'RYB 접근 방법 사용' ). JavaScript 에서 다시 작성되었습니다 .

사용하다:

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

처음 두 가지 색상은 흰색이고 검은 색입니다. 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]));
        }
    }
}

Java 답변을 제거했지만 필요한 경우이 요지에서 Java 버전을 볼 수 있습니다. gist.github.com/lotsabackscatter/3f6a658fd7209e010dad
Dylan Watson

3

R 2 라이너에서 David Crow의 방법 :

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

파스텔의 경우 더 높은 루마 다크 / 라이트 정수를 전달하십시오. 즉 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


1

David Crow의 원래 답변, IE 및 Nodejs 특정 코드의 JavaScript 적응이 포함되었습니다.

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

1

뚜렷한 색상을 사용하십시오 .

자바 스크립트로 작성되었습니다.

시각적으로 팔레트를 생성합니다 다른 색상 .

뚜렷한 색상을 구성 할 수 있습니다.

  • 팔레트에 몇 개의 색상이 있는지 선택하십시오
  • 색조를 특정 범위로 제한
  • 채도 (채도)를 특정 범위로 제한
  • 밝기를 특정 범위로 제한
  • 팔레트의 일반 품질 구성

0

그것들을 특정 밝기 내에 두게 할 수 있습니다. "neon"색상의 양을 약간 제어합니다. 예를 들어 "밝기"

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

특정 높은 범위 내에 있었고, 그것은 씻겨지고 밝은 색을 가질 것입니다. 반대로, 특정 하한 내에 있으면 더 어두워집니다. 이것은 미친 눈에 띄는 색상을 없애고 정말로 높거나 낮게 바운드를 선택하면 모두 흰색이나 검은 색에 상당히 가깝습니다.


0

알고리즘 적으로 원하는 것을 얻는 것은 어려울 것입니다. 사람들은 오랫동안 색 이론을 연구 해 왔으며 모든 규칙을 알지 못합니다.

그러나 일부있습니다 나쁜 색상 조합을 제거하는 데 사용할 수 규칙이 있습니다 (예 : 색상 충돌 및 보완 색상 선택 규칙).

도서관의 미술 섹션을 방문하여 색상 이론에 대한 책을 확인하여 색상을 만들기 전에 좋은 색상이 무엇인지 더 잘 이해하는 것이 좋습니다. 특정 조합이 작동하는 이유와 다른 조합이 왜 그런지 알지 못하는 것 같습니다. ' 티.

-아담


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

결과는 굉장한 색 무작위입니다! 그것은 자연 스럽지는 않지만 자연스러운 색상 그라디언트를 사용하며 유기적이고 제어 가능한 무지개 빛깔 / 파스텔 매개 변수로 보입니다.

perlin의 경우이 기능을 사용할 수 있으며 perlin의 빠른 지그재그 버전입니다.

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

여기 내가 만든 사이트에 대해 쓴 것이 있습니다. class가있는 모든 div에 대해 임의의 평면 배경색을 자동 생성합니다 .flat-color-gen. Jquery는 페이지에 CSS를 추가 할 목적으로 만 필요합니다. 이 방법의 주요 부분에는 필요하지 않습니다 generateFlatColorWithOrder().

JsFiddle 링크

(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);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.