Thuật toán để tạo ngẫu nhiên một bảng màu thẩm mỹ [đóng]


301

Tôi đang tìm kiếm một thuật toán đơn giản để tạo ra một số lượng lớn các màu sắc ngẫu nhiên, đẹp mắt. Vì vậy, không có màu neon điên, màu gợi nhớ đến phân, vv

Tôi đã tìm thấy giải pháp cho vấn đề này nhưng họ dựa vào bảng màu thay thế hơn RGB. Tôi thà chỉ sử dụng RGB thẳng hơn là ánh xạ qua lại. Những giải pháp khác cũng có thể tạo ra tối đa 32 màu hoặc ngẫu nhiên.

Bất cứ ý tưởng sẽ là tuyệt vời.


2
Tôi sẽ tạo một trang web tạo ra màu sắc ngẫu nhiên sau mỗi lần truy cập. Có một phiếu "đá màu này" / "màu này hút". Sau đó sắp xếp theo tỷ lệ phiếu bầu.
Nosredna

Bạn có thể kiểm tra HSL và HSV.
Jim Keener

48
"màu sắc gợi nhớ đến phân" Tôi yêu nó
lol

Đó không phải là một thuật toán.
Matt The Ninja

Tôi sẽ thêm một nhận xét kể từ khi câu hỏi được đóng lại. Tôi đã không thử nó, nhưng sẽ rất thú vị khi thử một cách theo phương thức fractal hoặc thủ tục, sử dụng thuật toán hoặc các biến thể của Midpoint Movement ( lighthouse3d.com/opengl/terrain/index.php?mpd2 ) hoặc Perlin Noise, nhưng thay vì độ cao để trộn các thành phần rgb của màu sắc.
alfoks

Câu trả lời:


426

Bạn có thể tính trung bình các giá trị RGB của các màu ngẫu nhiên với các màu không đổi:

(ví dụ trong 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;
}


Trộn các màu ngẫu nhiên với màu trắng (255, 255, 255) tạo ra phấn màu trung tính bằng cách tăng độ sáng trong khi vẫn giữ màu sắc của màu gốc. Những phấn màu được tạo ngẫu nhiên thường đi cùng nhau, đặc biệt là với số lượng lớn.

Dưới đây là một số màu pastel được tạo bằng phương pháp trên:

Đầu tiên


Bạn cũng có thể trộn màu ngẫu nhiên với một màu pastel không đổi, dẫn đến một tập hợp các màu trung tính được pha màu. Ví dụ: sử dụng màu xanh lam nhạt sẽ tạo ra các màu như sau:

Thứ hai


Đi xa hơn, bạn có thể thêm các heuristic vào trình tạo của mình có tính đến các màu bổ sung hoặc mức độ bóng, nhưng tất cả phụ thuộc vào ấn tượng bạn muốn đạt được với các màu ngẫu nhiên của bạn.

Một số tài nguyên bổ sung:


3
Sự cảnh báo duy nhất dường như là mất khả năng phân biệt. Bằng cách lấy trung bình của màu xanh lá cây và màu xanh lam với một màu như trắng, tất nhiên các màu sẽ di chuyển gần hơn với màu trắng và làm giảm sự khác biệt giữa chúng. Ví dụ: nếu bạn nhìn vào ảnh chụp màn hình đầu tiên: Khi những màu xanh lá cây đó nằm cạnh nhau, chắc chắn tôi có thể phân biệt chúng, nhưng nếu chúng không liền kề trong một số đồ họa được sản xuất thì sao? Có thể có vấn đề.
Zelphir Kaltstahl

Khi tạo thành phần màu ngẫu nhiên, hãy thử hạn chế giới hạn trên với một cái gì đó ít hơn, như 200.
Nickolodeon

87

Tôi sẽ sử dụng một bánh xe màu và đưa ra một vị trí ngẫu nhiên bạn có thể thêm góc vàng (137,5 độ)

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

để có được màu sắc khác nhau mỗi lần không trùng nhau.

Điều chỉnh độ sáng cho bánh xe màu, bạn cũng có thể nhận được các kết hợp màu sáng / tối khác nhau.

Tôi đã tìm thấy bài đăng trên blog này giải thích thực sự tốt vấn đề và giải pháp sử dụng tỷ lệ vàng.

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

CẬP NHẬT: Tôi vừa tìm thấy phương pháp khác này:

Nó được gọi là phương pháp RYB (đỏ, vàng, xanh) và được mô tả trong bài viết này:

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

như "Kết hợp màu lấy cảm hứng từ sơn".

Thuật toán tạo ra các màu và mỗi màu mới được chọn để tối đa hóa khoảng cách eidianidian của nó với các màu đã chọn trước đó.

Ở đây bạn có thể tìm thấy một triển khai tốt trong javascript:

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

CẬP NHẬT 2:

Tạp chí Khoa học Po Medialb vừa phát hành một công cụ có tên "Tôi muốn Huế" tạo ra các bảng màu cho các nhà khoa học dữ liệu. Sử dụng các không gian màu khác nhau và tạo các bảng màu bằng cách sử dụng các cụm vectơ hoặc lực vectơ (biểu đồ lực đẩy) Kết quả từ các phương pháp đó rất tốt, chúng cho thấy lý thuyết và cách thực hiện trong trang web của chúng.

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


iWantHue là câu trả lời. Đến đó Kinh ngạc.
Irongaze.com

23

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

Xem ý tưởng ở đây: http://blog.feftalfun.net/2008/07/random-pastel-colour-generator.html


Không hoàn toàn đúng: bạn cần phải zero-đệm cho số một con số quá ... Dù sao, đây là một fiddle làm việc cho Lookers: jsfiddle.net/RedDevil/LLYBQ ----- Scratch rằng ... tôi không chú ý bit + 127 ... Nhưng sau đó, điều này sẽ không tạo ra bóng tối.
kumarharsh

2
Ý tưởng ban đầu là tạo ra màu sắc dễ chịu tùy ý. Các bóng tối không có vẻ dễ chịu đối với tôi;)
motobói

11

Chuyển đổi sang bảng màu khác là một cách vượt trội hơn nhiều để làm điều này. Có một lý do họ làm điều đó: các bảng màu khác là 'nhận thức' - nghĩa là, họ đặt các màu có vẻ tương tự gần nhau và điều chỉnh một biến sẽ thay đổi màu theo cách có thể dự đoán được. Không có điều nào đúng với RGB, nơi không có mối quan hệ rõ ràng giữa các màu "kết hợp tốt với nhau".


6

Tôi đã thành công khi sử dụng TriadMatteCIE94 để tránh các màu tương tự. Hình ảnh sau đây sử dụng màu đầu vào đỏ, vàng và trắng. Xem tại đây .

Bộ ba + CIE94


5

Một câu trả lời không nên bỏ qua, bởi vì nó đơn giản và mang lại lợi thế, là lấy mẫu các bức ảnh và tranh vẽ ngoài đời thực. lấy mẫu nhiều pixel ngẫu nhiên như bạn muốn màu sắc ngẫu nhiên trên hình thu nhỏ của các bức ảnh nghệ thuật hiện đại, cezanne, van gogh, monnet, ảnh ... lợi thế là bạn có thể lấy màu theo chủ đề và chúng là màu hữu cơ. chỉ cần đặt 20 - 30 bức ảnh vào một thư mục và lấy mẫu ngẫu nhiên một bức ảnh ngẫu nhiên mỗi lần.

Chuyển đổi thành giá trị HSV là một thuật toán mã phổ biến cho bảng màu dựa trên tâm lý. hsv dễ dàng hơn để ngẫu nhiên.


1
mkweb.bcgsc.ca/color_summarizer/?analyze Đây là một công cụ trực tuyến có thể phân tích ảnh thật và trả về cho bạn Gograph của các giá trị RGB có thể cảm nhận được những gì ảnh thật có trong biểu đồ của họ .... trang web cực kỳ hữu ích, rất cần thiết nếu bạn đang cố gắng thiết kế các thuật toán tiên phong cho các màu ngẫu nhiên-
com.p Hiểu được

4

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

nguồn: https://stackoverflow.com/a/12266311/2875783


3

Dưới đây là trình tạo màu nhanh và bẩn trong C # (sử dụng 'phương pháp RYB' được mô tả trong bài viết này ). Đó là một bản viết lại từ JavaScript .

Sử dụng:

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

Hai màu đầu tiên có xu hướng là màu trắng và màu đen. Tôi thường bỏ qua chúng như thế này (sử dụng Linq):

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

Thực hiện:

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

Tôi đã xóa câu trả lời Java nhưng nếu được yêu cầu, phiên bản Java có thể được nhìn thấy trong Gist này: gist.github.com/lotsabackscatter/3f6a658fd7209e010dad
Dylan Watson

3

Phương pháp của David Crow trong một hai lớp R:

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

Đối với phấn màu, vượt qua các số nguyên tối / sáng luma cao hơn - tức là fnGetRandomColour (120, 250)

Tín dụng: tất cả các khoản tín dụng cho http://paulirish.com/2009/random-hex-color-code-snippets/ stackoverflow.com/questions/12043187/how-to-check-if-hex-color-is-too-black


1

JavaScript thích ứng với câu trả lời ban đầu của David Crow, bao gồm mã cụ thể của IE và 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) + ')';
}

Chạy chức năng bằng cách sử dụng:

generateRandomComplementaryColor(240, 240, 240);

1

Sử dụng màu sắc riêng biệt .

Viết bằng javascript.

Nó tạo ra một bảng màu sắc khác biệt trực quan .

màu sắc riêng biệt có cấu hình cao:

  • Chọn có bao nhiêu màu trong bảng màu
  • Hạn chế màu sắc trong một phạm vi cụ thể
  • Giới hạn sắc độ (độ bão hòa) trong một phạm vi cụ thể
  • Hạn chế độ sáng ở một phạm vi cụ thể
  • Cấu hình chất lượng chung của bảng màu

0

bạn có thể có chúng trong một độ sáng nhất định. điều đó sẽ kiểm soát lượng màu của màu "neon" một chút. ví dụ, nếu "độ sáng"

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

là trong một giới hạn cao nhất định, nó sẽ bị trôi đi, màu sáng với nó. Ngược lại, nếu nó nằm trong một giới hạn thấp nhất định, nó sẽ tối hơn. Điều này sẽ loại bỏ bất kỳ màu sắc nổi bật, điên rồ nào và nếu bạn chọn một ràng buộc thực sự cao hoặc thực sự thấp, tất cả chúng sẽ khá gần với màu trắng hoặc đen.


0

Sẽ rất khó để có được những gì bạn muốn về mặt thuật toán - mọi người đã nghiên cứu lý thuyết màu sắc trong một thời gian dài và họ thậm chí không biết tất cả các quy tắc.

Tuy nhiên, có một số quy tắc mà bạn có thể sử dụng để loại bỏ các kết hợp màu xấu (nghĩa là có các quy tắc để trộn màu và chọn màu bổ sung).

Tôi khuyên bạn nên truy cập phần nghệ thuật của thư viện và kiểm tra sách về lý thuyết màu sắc để hiểu rõ hơn về màu sắc tốt trước khi bạn thử tạo ra - có vẻ như bạn thậm chí không biết tại sao một số kết hợp nhất định lại hoạt động và những người khác không ' t.

-Adam


0

Tôi thực sự khuyên bạn nên sử dụng chức năng đổ bóng CG HSVtoRGB, chúng thật tuyệt vời ... nó mang lại cho bạn khả năng kiểm soát màu sắc tự nhiên như họa sĩ thay vì điều khiển như màn hình crt, mà bạn có lẽ không có khả năng!

Đây là một cách để tạo ra 1 giá trị float. tức là màu xám, thành 1000 DS kết hợp màu sắc, độ sáng và độ bão hòa, v.v .:

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

kết quả là TĂNG CƯỜNG MÀU TUYỆT VỜI! nó không tự nhiên nhưng nó sử dụng độ dốc màu tự nhiên và nó trông có vẻ hữu cơ và có thể kiểm soát được các thông số màu pastel / pastel.

Đối với perlin, bạn có thể sử dụng chức năng này, đây là phiên bản nhanh zig zag của 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

Đây là một cái gì đó tôi đã viết cho một trang web tôi đã thực hiện. Nó sẽ tự động tạo màu nền phẳng ngẫu nhiên cho bất kỳ div nào với lớp .flat-color-gen. Jquery chỉ được yêu cầu cho mục đích thêm css vào trang; nó không cần thiết cho phần chính của điều này, đó là generateFlatColorWithOrder()phương pháp.

Liên kết 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);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.