2012-06-20 22 views
37

任意の文字列をRGBカラー値にハッシュする方法に関するベストプラクティスはありますか?より一般的には、3バイトまでです。ハッシュ文字列をRGBカラーに変換

あなたは質問しています。これはいつ必要ですか?それは私にとって重要ではありませんが、GitHub network pageのチューブグラフを想像してみてください。すべての色のラインが別個のgitブランチを意味

git branches

:そこにはこのような何かを見ることができます。これらのブランチに色を付けるローテクのアプローチは、CLUT(カラールックアップテーブル)です。より洗練されたバージョンは、次のようになります。

$branchColor = hashStringToColor(concat($username,$branchname)); 

あなたは、静的な色にあなたが枝の表現を見るたびにしたいので。ボーナスポイントの場合:どのようにしてそのハッシュ関数の均等な色分布を保証しますか?

私の質問に対する答えはhashStringToColor()の実装になっています。

答えて

26

良いハッシュ関数は、キー空間にほぼ均一な分布を提供します。これにより、ランダムな32ビットの数値を3バイトのRGB空間に変換する方法がわかりません。私はちょうど低い3バイトを取ることと間違って何も見る。そこに任意のJavascriptのユーザーの場合

int hash = string.getHashCode(); 
int r = (hash & 0xFF0000) >> 16; 
int g = (hash & 0x00FF00) >> 8; 
int b = hash & 0x0000FF; 
+0

うまく働いた、ありがとう。 – clayzermk1

+9

読み取り可能な色(十分なコントラストと彩度を確保するなど)を確保したい場合は、それ以上の作業を行う必要があります。 HSVやLABで作業しやすく、RGBに変換する方が簡単かもしれません。 – naught101

+0

素敵な解決策! –

2

例として、this is how Java calculates the hashcode of a string(1494行目以降)。 intを返します。次に、 "RGB互換"番号を取得するために、そのintのモジュロを16,777,216(2^24 = 3バイト)で計算することができます。

決定的な計算であるため、同じ単語が常に同じ色になります。ハッシュ衝突の可能性(同じ色を持つ2つの文字列)は小さいです。色の分布はわかりませんが、おそらくかなりランダムです。

+0

私は衝突が発生したときにそれはあなたが例のように(近所の色にする必要はありません限り、問題の多くはありませんので、ハッシュ衝突は、無視することができると思います与えられた)が異なっている。 –

+1

色分布のランダム性は審美的な問題かもしれません。 「醜い」色がたくさんありますが、構成要素にある種の重みを適用して、より美しい:醜い比率を試すことは実用的な考えかもしれません。 :) – Wug

19

、私はerlycoderからdjb2ハッシュ関数とジェフ・フォスター@から受け入れ答えを組み合わせます。

結果質問あたり:

function djb2(str){ 
    var hash = 5381; 
    for (var i = 0; i < str.length; i++) { 
    hash = ((hash << 5) + hash) + str.charCodeAt(i); /* hash * 33 + c */ 
    } 
    return hash; 
} 

function hashStringToColor(str) { 
    var hash = djb2(str); 
    var r = (hash & 0xFF0000) >> 16; 
    var g = (hash & 0x00FF00) >> 8; 
    var b = hash & 0x0000FF; 
    return "#" + ("0" + r.toString(16)).substr(-2) + ("0" + g.toString(16)).substr(-2) + ("0" + b.toString(16)).substr(-2); 
} 

UPDATEは:常に@alexcによって編集に基づいて#000000形式の16進文字列を返すために返される文字列を修正(感謝!)。

+3

"rgb(" + r + "、" + g + "、" + b + ")" –

+1

@StuGla:16進形式が要件。それを今読んでいると思われません。質問は一般的に尋ねられたので、私は著者が色文字列の形式よりもハッシュアルゴリズムに興味があると思う。しかし、質問の文脈がCSSなら、あなたはそれを行うためにもっときれいな方法でしょう。乾杯人、ありがとう! – clayzermk1

+0

@StuGla:透過性を追加することもできます。 – MastaBaba

8

私は他のすべてのソリューションを試しましたが、同様の文字列(string1とstring2)が私の好みにあまりにも似ている色を生成することがわかりました。したがって、私は他の人の意見や考えに影響されて自分自身を作りました。

これは文字列のMD5チェックサムを計算し、最初の6桁の16進数でRGB 24ビットコードを定義します。 。次のように

MD5機能は、jQueryのプラグインオープンソースである JS関数は行く:

function getRGB(str){ 
    var hash = $.md5(str); 
    var rgb = '#' + hash.substring(0,2) + hash.substring(2,4) + hash.substring(4,6); 
    return rgb; 
} 

本実施例へのリンクがjsFiddleです。入力フィールドに文字列を入力してEnterキーを押すだけで、結果を比較することができます。

+0

3行目を簡略化して、 'var rgb = '#' + hash.substring(0,6);' –

+0

*他のソリューションを試しました(...)*いいえ、あなたはいません:) Jeff Fosterの答え**無限の**多くのソリューションを持つ家族を説明します。あなたの解決策は、この家族のメンバー、btwです。 –