JavaScript를 사용하여 문자열을 기반으로 16 진수 색상 만들기


141

오래된 문자열 (일반적으로 단일 단어 임)을 받아들이고 어떻게 든 함수를 만들고 싶습니다. 사이의 16 진수 값을 생성 #000000하고 #FFFFFF난 HTML 요소의 색상으로 사용할 수 있도록를.

#FFF덜 복잡한 16 진수 값 (예 :) 일 수도 있습니다. 실제로 '웹 안전'팔레트의 색상이 이상적입니다.


2
샘플 입력 및 / 또는 유사한 질문에 대한 링크를 제공 할 수 있습니까?
qw3n

2
답은 아니지만 다음과 같은 유용한 정보가 있습니다. 16 진수를 정수로 변환하려면을 사용하십시오 parseInt(hexstr, 10). 정수를 16 진수로 변환하려면을 사용하십시오 n.toString(16). 여기서 n은 정수입니다.
Cristian Sanchez

@ qw3n-샘플 입력 : 'Medicine', 'Surgery', 'Neurology', 'General Practice'와 같이 짧고 평범한 오래된 텍스트 문자열 .3에서 20 문자 사이의 범위는 찾을 수 없습니다. 다른 하나이지만 여기에 Java 질문이 있습니다 : stackoverflow.com/questions/2464745/… @Daniel-감사합니다. 나는 앉아서 또 다른 심각한 일을해야합니다. 유용 할 수 있습니다.
Darragh Enright

답변:


176

임의의 문자열대한 Compute hex 색상 코드 에서 Javascript로 Java를 이식하면 됩니다.

function hashCode(str) { // java String#hashCode
    var hash = 0;
    for (var i = 0; i < str.length; i++) {
       hash = str.charCodeAt(i) + ((hash << 5) - hash);
    }
    return hash;
} 

function intToRGB(i){
    var c = (i & 0x00FFFFFF)
        .toString(16)
        .toUpperCase();

    return "00000".substring(0, 6 - c.length) + c;
}

변환하려면 다음을 수행하십시오.

intToRGB(hashCode(your_string))

1
큰! 고마워, 이것은 잘 작동합니다. 나는 비트 연산자와 물건에 대해 많이 알지 못하므로 그것을 포팅하는 데 도움을 주셔서 감사합니다.
Darragh Enright

다음과 같은 16 진 줄을 ("00" + ((this >> 24) & 0xFF).toString(16)).slice(-2) + ("00" + ((this >> 16) & 0xFF).toString(16)).slice(-2) + ("00" + ((this >> 8) & 0xFF).toString(16)).slice(-2) + ("00" + (this & 0xFF).toString(16)).slice(-2);
채워야합니다

2
많은 음악 장르 태그를 배경색으로 변환하고있어 시간이 많이 절약되었습니다.
Kyle Pennell 5

나는 이것을 PHP로 변환 할 수 있기를 바랍니다.
Nimitz E.

6
비슷한 문자열에 대해 거의 같은 색으로 몇 가지 문제가 있습니다. intToRGB(hashCode('hello1')) -> "3A019F" intToRGB(hashCode('hello2')) -> "3A01A0" 최종 해시 값에 곱셈을 추가하여 코드를 향상시킵니다.return 100 * hash;
SirWojtek

185

다음은 6 자리 색상 코드를 일관되게 반환하는 CD Sanchez의 답변에 대한 수정입니다.

var stringToColour = function(str) {
  var hash = 0;
  for (var i = 0; i < str.length; i++) {
    hash = str.charCodeAt(i) + ((hash << 5) - hash);
  }
  var colour = '#';
  for (var i = 0; i < 3; i++) {
    var value = (hash >> (i * 8)) & 0xFF;
    colour += ('00' + value.toString(16)).substr(-2);
  }
  return colour;
}

용법:

stringToColour("greenish");
// -> #9bc63b

예:

http://jsfiddle.net/sUK45/

(대체 / 간단한 솔루션은 'rgb (...)'스타일 색상 코드를 반환하는 것을 포함 할 수 있습니다.)


3
이 코드는 NoSQL 자동 생성 ID와 함께 훌륭하게 작동하며 동일한 사용자에 대해 매번 색상이 동일합니다.
deviavir

16 진수 코드의 투명성을 위해 알파 채널이 필요했습니다. 이것은 도움이되었습니다 (내 16 진수 코드 끝에 알파 채널에 두 자리 숫자 추가) : gist.github.com/lopspower/03fb1cc0ac9f32ef38f4
Husterknupp

@Tjorriemorrie 색이 아니라 색임을 지적 해주었습니다. 예, 그렇습니다. 그것은 실제로 주제가 아니지만 나에게 중요한 것입니다 (실제로 그것을 입력 할 때 나는 '색상'이라고 두 번 철자했습니다!). 감사합니다.
Pryftan

Chrome / Windows 및 Chrome + Android와 같이 다른 브라우저 / OS에서 동일한 문자열에 대해 색상이 다르다는 점에 흥미가 있습니다. 내 이메일 => 컬러는 한 쪽은 파란색이고 다른 한 쪽은 녹색입니다. 왜 그런지 알아?
avenmore

43

HTML 요소의 색상이 풍부하고 풍부하기를 원했지만 CSS가 이제 hsl () 색상을 지원한다는 사실에 놀랐습니다. 따라서 전체 솔루션은 다음과 같습니다.

N "고유 한"색상을 자동으로 생성하는 방법 도 참조하십시오 . 이와 유사한 더 많은 대안이 필요합니다.

function colorByHashCode(value) {
    return "<span style='color:" + value.getHashCode().intToHSL() + "'>" + value + "</span>";
}
String.prototype.getHashCode = function() {
    var hash = 0;
    if (this.length == 0) return hash;
    for (var i = 0; i < this.length; i++) {
        hash = this.charCodeAt(i) + ((hash << 5) - hash);
        hash = hash & hash; // Convert to 32bit integer
    }
    return hash;
};
Number.prototype.intToHSL = function() {
    var shortened = this % 360;
    return "hsl(" + shortened + ",100%,30%)";
};

document.body.innerHTML = [
  "javascript",
  "is",
  "nice",
].map(colorByHashCode).join("<br/>");
span {
  font-size: 50px;
  font-weight: 800;
}

HSL에서 색조, 채도, 가벼움. 따라서 0-359 사이의 색조는 모든 색상을 얻을 수 있으며 채도는 색상을 얼마나 풍부하게 원하는지, 100 %는 저에게 효과적입니다. 밝기는 깊이를 결정하고, 50 %는 보통, 25 %는 어두운 색, 75 %는 파스텔입니다. 내 색 구성표에 가장 적합하기 때문에 30 %가 있습니다.


3
매우 다양한 솔루션.
MastaBaba

2
색상이 얼마나 화려한지를 결정할 수있는 솔루션 공유를위한 Thx!
Florian Bauer

@haykam 스 니펫으로 만들어 주셔서 감사합니다!
Thymine

이 접근법은 내 앱에 필요한 생동감 / 미묘함을주는 데 실제로 유용합니다. 임의의 16 진수는 채도와 밝기가 너무 다양하여 대부분의 상황에서 유용합니다. 감사합니다!
simey.me

이 솔루션은 너무 적은 색상을 반환합니다.
catamphetamine 2015 년

9

임의의 색상을 생성하면 내 취향에 대비가 충분하지 않은 색상이 생성되는 경향이 있습니다. 내가 찾은 가장 쉬운 방법은 매우 다른 색상 목록을 미리 채우는 것입니다. 모든 문자열에 대해 목록에서 다음 색상을 지정하십시오.

// Takes any string and converts it into a #RRGGBB color.
var StringToColor = (function(){
    var instance = null;

    return {
    next: function stringToColor(str) {
        if(instance === null) {
            instance = {};
            instance.stringToColorHash = {};
            instance.nextVeryDifferntColorIdx = 0;
            instance.veryDifferentColors = ["#000000","#00FF00","#0000FF","#FF0000","#01FFFE","#FFA6FE","#FFDB66","#006401","#010067","#95003A","#007DB5","#FF00F6","#FFEEE8","#774D00","#90FB92","#0076FF","#D5FF00","#FF937E","#6A826C","#FF029D","#FE8900","#7A4782","#7E2DD2","#85A900","#FF0056","#A42400","#00AE7E","#683D3B","#BDC6FF","#263400","#BDD393","#00B917","#9E008E","#001544","#C28C9F","#FF74A3","#01D0FF","#004754","#E56FFE","#788231","#0E4CA1","#91D0CB","#BE9970","#968AE8","#BB8800","#43002C","#DEFF74","#00FFC6","#FFE502","#620E00","#008F9C","#98FF52","#7544B1","#B500FF","#00FF78","#FF6E41","#005F39","#6B6882","#5FAD4E","#A75740","#A5FFD2","#FFB167","#009BFF","#E85EBE"];
        }

        if(!instance.stringToColorHash[str])
            instance.stringToColorHash[str] = instance.veryDifferentColors[instance.nextVeryDifferntColorIdx++];

            return instance.stringToColorHash[str];
        }
    }
})();

// Get a new color for each string
StringToColor.next("get first color");
StringToColor.next("get second color");

// Will return the same color as the first time
StringToColor.next("get first color");

이것은 64 색으로 제한되지만 대부분의 인간은 그 이후의 차이점을 실제로 알 수 없습니다. 항상 더 많은 색상을 추가 할 수 있다고 가정합니다.

이 코드는 하드 코딩 된 색상을 사용하지만 최소한 개발 과정에서 프로덕션 환경에서 색상 사이의 대비 정도를 알고 있어야합니다.

이 SO answer 에서 색상 목록이 해제되었으며 색상이 더 많은 다른 목록이 있습니다.


Fwiw에는 대비를 결정하는 알고리즘이 있습니다. 나는 몇 년 전에 (C로) 무언가를 썼습니다. 그것에 대해 너무 걱정하고 어쨌든 오래된 대답이지만 대비를 결정할 수있는 방법이 있다고 지적했습니다.
Pryftan

7

해시에서 색상을 생성 할 수있는 Please.js에 대한 풀 요청 을 열었습니다 .

문자열을 다음과 같이 색상에 매핑 할 수 있습니다.

const color = Please.make_color({
    from_hash: "any string goes here"
});

예를 들어, "any string goes here"로 리턴 "#47291b"
"another!"같은 반환"#1f0c3d"


추가해 주셔서 감사합니다. Google받은 편지함의 이름을 기반으로 문자가 포함 된 서클을 생성하고 싶은 분 :)
marcus7777 10

이 대답을 보았을 때, 나는 완벽하다고 생각했습니다. 이제 색상 스키마에 대해 생각하여 매우 임의의 색상을 생성하지 않아야합니다. 그런 다음 Please.js make_color 옵션에 대해 읽고 내 얼굴에 아름다운 미소를지었습니다.
panchicore

6

입력이 간단한 해시가 전체 색상 스펙트럼을 사용하기에 충분히 다르지 않은 경우 해시 함수 대신 시드 난수 생성기를 사용할 수 있습니다.

Joe Freeman의 답변에서 나온 컬러 코더와 David Bau의 시드 난수 생성기를 사용하고 있습니다.

function stringToColour(str) {
    Math.seedrandom(str);
    var rand = Math.random() * Math.pow(255,3);
    Math.seedrandom(); // don't leave a non-random seed in the generator
    for (var i = 0, colour = "#"; i < 3; colour += ("00" + ((rand >> i++ * 8) & 0xFF).toString(16)).slice(-2));
    return colour;
}

5

임의의 색상에 대한 또 다른 솔루션 :

function colorize(str) {
    for (var i = 0, hash = 0; i < str.length; hash = str.charCodeAt(i++) + ((hash << 5) - hash));
    color = Math.floor(Math.abs((Math.sin(hash) * 10000) % 1 * 16777216)).toString(16);
    return '#' + Array(6 - color.length + 1).join('0') + color;
}

그것은 나를 위해 일하는 것들이 혼합되어 있습니다. 나는 JFreeman Hash 함수 (또한이 스레드의 답변)와 Asykäri pseudo random function을 사용했습니다. 여기에서 사용 했고 일부 패딩과 수학을 사용했습니다.

멋지게 보이고 기능을 수행하지만 함수가 균일하게 분산 된 색상을 생성한다고 의심합니다.


'0'.repeat(...)유효하지 않은 자바 스크립트
kikito

@kikito fair, 아마도 프로토 타입이 어떻게 든 확장되었을 것입니다 (JQuery?). 어쨌든, 함수를 편집 했으므로 자바 스크립트 일뿐입니다. 지적 해 주셔서 감사합니다.
estani

@kikito 유효한 ES6이지만 사용하면 브라우저 간 호환성이 무시됩니다.
패트릭 로버츠

5

hashCodeCristian Sanchez의 답변 hsl과 현대적인 자바 스크립트 에서 as를 사용하면 다음 과 같이 대비가 좋은 색상 선택기를 만들 수 있습니다.

function hashCode(str) {
  let hash = 0;
  for (var i = 0; i < str.length; i++) {
    hash = str.charCodeAt(i) + ((hash << 5) - hash);
  }
  return hash;
}

function pickColor(str) {
  return `hsl(${hashCode(str) % 360}, 100%, 80%)`;
}

one.style.backgroundColor = pickColor(one.innerText)
two.style.backgroundColor = pickColor(two.innerText)
div {
  padding: 10px;
}
<div id="one">One</div>
<div id="two">Two</div>

hsl이므로 원하는 대비를 얻기 위해 휘도를 조정할 수 있습니다.

function hashCode(str) {
  let hash = 0;
  for (var i = 0; i < str.length; i++) {
    hash = str.charCodeAt(i) + ((hash << 5) - hash);
  }
  return hash;
}

function pickColor(str) {
  // Note the last value here is now 50% instead of 80%
  return `hsl(${hashCode(str) % 360}, 100%, 50%)`;
}

one.style.backgroundColor = pickColor(one.innerText)
two.style.backgroundColor = pickColor(two.innerText)
div {
  color: white;
  padding: 10px;
}
<div id="one">One</div>
<div id="two">Two</div>


4

다음은 입력 문자열을 기반으로 미적으로 유쾌한 파스텔 색상을 생성하는 솔루션입니다. 문자열의 처음 두 문자를 임의의 시드로 사용하고 해당 시드를 기반으로 R / G / B를 생성합니다.

시드가 처음 두 개가 아닌 문자열에있는 모든 문자의 XOR이되도록 쉽게 확장 할 수 있습니다.

David Crow의 답변에서 영감을 얻었습니다. 미적으로 유쾌한 색상 팔레트를 임의로 생성하는 알고리즘

//magic to convert strings to a nice pastel colour based on first two chars
//
// every string with the same first two chars will generate the same pastel colour
function pastel_colour(input_str) {

    //TODO: adjust base colour values below based on theme
    var baseRed = 128;
    var baseGreen = 128;
    var baseBlue = 128;

    //lazy seeded random hack to get values from 0 - 256
    //for seed just take bitwise XOR of first two chars
    var seed = input_str.charCodeAt(0) ^ input_str.charCodeAt(1);
    var rand_1 = Math.abs((Math.sin(seed++) * 10000)) % 256;
    var rand_2 = Math.abs((Math.sin(seed++) * 10000)) % 256;
    var rand_3 = Math.abs((Math.sin(seed++) * 10000)) % 256;

    //build colour
    var red = Math.round((rand_1 + baseRed) / 2);
    var green = Math.round((rand_2 + baseGreen) / 2);
    var blue = Math.round((rand_3 + baseBlue) / 2);

    return { red: red, green: green, blue: blue };
}

GIST는 다음과 같습니다 : https://gist.github.com/ro-sharp/49fd46a071a267d9e5dd


나는 이것이 정말로 이상한 방법이라고 말해야합니다. 그것은 일종의 작품이지만 사용 가능한 색상이 많지 않습니다. 처음 두 색상의 XOR은 순서를 구분하지 않으므로 문자 조합 만 있습니다. 색상 수를 늘리기위한 간단한 추가 작업은 var seed = 0입니다. for (var in input_str) {seed ^ = i; }
Gussoh

예, 실제로 생성하려는 색상 수에 따라 다릅니다. 이 경우 UI에서 다른 창을 만들고 무지개 대신 제한된 수의 색상을 원했던 것을 기억합니다.)
Robert Sharp

1

또 다른 시도는 다음과 같습니다.

function stringToColor(str){
  var hash = 0;
  for(var i=0; i < str.length; i++) {
    hash = str.charCodeAt(i) + ((hash << 3) - hash);
  }
  var color = Math.abs(hash).toString(16).substring(0, 6);

  return "#" + '000000'.substring(0, 6 - color.length) + color;
}

1

실제로 필요한 것은 좋은 해시 함수입니다. 노드에서 나는 단지

const crypto = require('crypto');
function strToColor(str) {
    return '#' + crypto.createHash('md5').update(str).digest('hex').substr(0, 6);
}

0

Java로 이것을 변환합니다.

모든 탱크.

public static int getColorFromText(String text)
    {
        if(text == null || text.length() < 1)
            return Color.BLACK;

        int hash = 0;

        for (int i = 0; i < text.length(); i++)
        {
            hash = text.charAt(i) + ((hash << 5) - hash);
        }

        int c = (hash & 0x00FFFFFF);
        c = c - 16777216;

        return c;
    }

-1

이 기능은 트릭을 수행합니다. 이것은 이 repo의 상당히 긴 구현에 대한 적응입니다 .

const color = (str) => {
    let rgb = [];
    // Changing non-hexadecimal characters to 0
    str = [...str].map(c => (/[0-9A-Fa-f]/g.test(c)) ? c : 0).join('');
    // Padding string with zeroes until it adds up to 3
    while (str.length % 3) str += '0';

    // Dividing string into 3 equally large arrays
    for (i = 0; i < str.length; i += str.length / 3)
        rgb.push(str.slice(i, i + str.length / 3));

    // Formatting a hex color from the first two letters of each portion
    return `#${rgb.map(string => string.slice(0, 2)).join('')}`;
}

이것은 매우 어두운 값을 많이 생성합니다.
Langdon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.