0

I managed to generate a random hex color from a string :

function StringToColorFilter() {
    var hashString = function (chaine) {
        var hash = 0, i, chr, len;
        if (chaine.length == 0)
            return hash;
        for (i = 0, len = chaine.length; i < len; i++) {
            chr = chaine.charCodeAt(i);
            hash = ((hash << 5) - hash) + chr;
            hash |= 0; // Convert to 32bit integer
        }
        return hash;
    };
    return function (chaine) {
        return "#" + ("FFFFFF" + Math.abs(hashString(chaine) % 16777216).toString(16)).substr(-6);
    };
}

Example : StringToColorFilter()("MyString") => #393303 (no luck this color suxx)

So now :

  • I want to avoid white, bland, graying or pale colors
  • I want to generate only intense/strong/colorful colors

I first tried to remove one component (red, green, or blue) or two, but that removes too many possibilities and i can still have ugly colors.

Then i tried to remove extremum (F/E and 0/1) values. But i can still have grey.

Some algorithm ideas ?

antoinestv
  • 3,286
  • 2
  • 23
  • 39
  • 2
    For intensity of the color, you may need to convert it to either `HSV` or `HSL` colorspace which represents the chrome, intensity, and saturation components separately. So you can manipulate the saturation and intensity of the color easier. – TaoPR Jul 02 '15 at 12:56
  • Indeed ! Good idea ! =) – antoinestv Jul 02 '15 at 13:00
  • 1
    FYI, converting from `RGB` to `HSV` back and forth may cost some loss at some degree. You may need to be aware of this too. – TaoPR Jul 02 '15 at 13:04
  • I just saw that i want to fix S and V to 100 and only change H from 0 to 255 (I don't need more colors) to have only intense colors. So i will only generate the H from my hash then convert it only once to RGB. – antoinestv Jul 02 '15 at 13:08
  • 2
    @TaoP.R. this should be minimal if you don't round until you're completely finished ( http://stackoverflow.com/questions/17242144/javascript-convert-hsb-hsv-color-to-rgb-accurately/17243070#17243070 ) – Paul S. Jul 02 '15 at 13:08
  • 1
    @PaulS. That's very helpful advice. Antoine, you may want to look into this approach. – TaoPR Jul 02 '15 at 13:10
  • 1
    To avoid any grayscale, you need to enforce variation between the rgb values. Any gray between white and black means that r=g=b. So if you make sure they are not the same, and even better, significantly different - you will avoid all grays. – mac Jul 02 '15 at 13:12

1 Answers1

0

Solution thanks to Tao P. R., Paul S. : Using HSV format and fixing S and V.

In my case I used S = 0.59 and V = 0.87. So I have only 360 colors left but it is enough for me, and this solution make sure I have the same saturation and brightness over all my colors.

function StringToColorFilter() {
    var hashString = function (chaine) {
        var hash = 0, i, chr, len;
        if (chaine.length == 0)
            return hash;
        for (i = 0, len = chaine.length; i < len; i++) {
            chr = chaine.charCodeAt(i);
            hash = ((hash << 5) - hash) + chr;
            hash |= 0; // Convert to 32bit integer
        }
        return hash;
    };
    function HSVtoRGB(h, s, v) {
        var r, g, b, i, f, p, q, t;
        i = Math.floor(h * 6);
        f = h * 6 - i;
        p = v * (1 - s);
        q = v * (1 - f * s);
        t = v * (1 - (1 - f) * s);
        switch (i % 6) {
            case 0:
                r = v, g = t, b = p;
                break;
            case 1:
                r = q, g = v, b = p;
                break;
            case 2:
                r = p, g = v, b = t;
                break;
            case 3:
                r = p, g = q, b = v;
                break;
            case 4:
                r = t, g = p, b = v;
                break;
            case 5:
                r = v, g = p, b = q;
                break;
        }
        return {
            r: Math.floor(r * 255),
            g: Math.floor(g * 255),
            b: Math.floor(b * 255)
        };
    }
    return function (chaine) {
        var couleur = HSVtoRGB(Math.abs(hashString(chaine) % 360) / 360, 0.59, 0.87);
        return "#" + ("FF" + couleur.r.toString(16)).substr(-2) + ("FF" + couleur.g.toString(16)).substr(-2) + ("FF" + couleur.b.toString(16)).substr(-2);
    };
}
Community
  • 1
  • 1
antoinestv
  • 3,286
  • 2
  • 23
  • 39