web-dev-qa-db-ja.com

プログラムで16進数の色を明るくしたり暗くしたりする(またはRGB、ブレンドカラー)

プログラム的に16進数を特定の量だけ明るくしたり暗くしたりするために私が取り組んでいた関数です。色には"3F6D2A"のような文字列(col)を、明るさまたは暗さの量にはbase10整数(amt)を渡すだけです。暗くするには、負の数(つまり-20)を渡します。

私がこれをする理由は私が見つけたすべての解決策のためでした、これまでのところ、それらは問題を過度に複雑にしているようでした。そして、私はそれがほんの数行のコードで実行できると感じました。あなたが何か問題を見つけたか、それをスピードアップするためにそれをするために何か調整があったら私に知らせてください。

function LightenDarkenColor(col,amt) {
    col = parseInt(col,16);
    return (((col & 0x0000FF) + amt) | ((((col>> 8) & 0x00FF) + amt) << 8) | (((col >> 16) + amt) << 16)).toString(16);
}

開発用には、こちらのほうが読みやすいバージョンです。

function LightenDarkenColor(col,amt) {
    var num = parseInt(col,16);
    var r = (num >> 16) + amt;
    var b = ((num >> 8) & 0x00FF) + amt;
    var g = (num & 0x0000FF) + amt;
    var newColor = g | (b << 8) | (r << 16);
    return newColor.toString(16);
}

そして最後に、最初に "#"を付けても付けなくてもいい色を扱うバージョンがあります。不適切な色の値に合わせて調整する:

function LightenDarkenColor(col,amt) {
    var usePound = false;
    if ( col[0] == "#" ) {
        col = col.slice(1);
        usePound = true;
    }

    var num = parseInt(col,16);

    var r = (num >> 16) + amt;

    if ( r > 255 ) r = 255;
    else if  (r < 0) r = 0;

    var b = ((num >> 8) & 0x00FF) + amt;

    if ( b > 255 ) b = 255;
    else if  (b < 0) b = 0;

    var g = (num & 0x0000FF) + amt;

    if ( g > 255 ) g = 255;
    else if  ( g < 0 ) g = 0;

    return (usePound?"#":"") + (g | (b << 8) | (r << 16)).toString(16);
}

さて、今は2〜3行ではありませんが、はるかに簡単に見えます。 "#"を使用していない場合に範囲外の色をチェックする必要がない場合は、2、3行です。

"#"を使用しない場合は、次のようなコードに追加するだけです。

var myColor = "3F6D2A";
myColor = LightenDarkenColor(myColor,10);
thePlaceTheColorIsUsed = ("#" + myColor);

私の主な質問は、私はここで正しいのかと思います。これはいくつかの(正常な)状況を網羅していませんか?

440
Pimp Trizkit

さて、この答えはそれ自身の獣になりました。多くの新しいバージョン、それは愚かになっていました。この回答に貢献してくれた多くの人々に感謝します。しかし、大衆のためにそれを単純に保つために。私はこの答えの進化のすべてのバージョン/歴史を私の github にアーカイブしました。そしてStackOverflowの最新版を使って、ここからきれいに始めました。このバージョンでは、 Mike 'Pomax' Kamermans に感謝します。彼は私に新しい数学を与えた。


この関数(pSBC)は、16進数またはRGBのWebカラーを取ります。 pSBCは、濃くしたり薄くしたり、2色目で混ぜたりすることができます。また、右から右へ渡すこともできますが、HexからRGB(Hex2RGB)またはRGBからHex(RGB2Hex)に変換できます。あなたがいなくてもあなたがどんなカラーフォーマットを使っているかさえ知らない。

これは本当に速く走ります、おそらく最も速いです、特にその多くの機能を考えると。制作には長い時間がかかりました。私の github の全体の話を見てください。あなたがシェードまたはブレンドするために絶対に最小で最速の方法を望むならば、以下のMicro Functionsを見て、そして2ライナースピードデーモンのうちの1つを使ってください。激しいアニメーションには最適ですが、このバージョンではほとんどのアニメーションに十分な速さがあります。

この機能は対数混合または線形混合を使用します。ただし、色を適切に明るくしたり暗くしたりするためにHSLに変換することはできません。したがって、この関数からのの結果は、HSLを使用する非常に大きくて遅い関数とは異なります

pSBCでのjsFiddle

github> pSBC Wiki

特徴:

  • 文字列の形式で標準の16進数の色を自動検出して受け入れます。例えば、"#AA6622"または"#bb551144"です。
  • 文字列の形式で標準RGB色を自動検出して受け入れます。例えば、"rgb(123,45,76)"または"rgba(45,15,74,0.45)"です。
  • 色をパーセントで白または黒にします。
  • 割合で色を混ぜ合わせます。
  • Hex2RGBとRGB2Hexの変換、または単独での変換を行います。
  • #RGB(または#RGBA)の形式で、3桁(または4桁w/alpha)のHEXカラーコードを受け入れます。それはそれらを拡張します。例:"#C41""#CC4411"になります。
  • 受け入れて(リニア)アルファチャンネルをブレンドします。 c0(from)カラーまたはc1(to)カラーのいずれかにアルファチャンネルがある場合、返される色はアルファチャンネルになります。両方の色にアルファチャンネルがある場合、返される色は指定されたパーセンテージを使用して2つのアルファチャンネルを線形ブレンドしたものになります(通常のカラーチャンネルの場合と同様)。 2つの色のうち1つだけにアルファチャンネルがある場合、このアルファは返される色にそのまま渡されます。これにより、透明度を維持しながら透明色をブレンド/シェーディングすることができます。または、透明度レベルもブレンドする必要がある場合は、両方の色にアルファがあるようにしてください。シェーディングすると、アルファチャンネルがまっすぐに通過します。アルファチャンネルもシェーディングする基本的なシェーディングが必要な場合は、c1(to)の色としてrgb(0,0,0,1)またはrgb(255,255,255,1)を使用します(またはそれに相当する16進数)。 RGBカラーの場合、返されるカラーのアルファチャンネルは小数点以下第3位に丸められます。
  • RGB2HexとHex2RGBの変換は、ブレンディングを使用するときに暗黙的に行われます。 c0(from)の色に関係なく。返された色は常にc1(to)色の色フォーマットになります(存在する場合)。 c1(to)の色がない場合は、'c'の色としてc1を渡すと、c0の色が何であっても色付けされ変換されます。変換のみが必要な場合は、パーセンテージ(p)として0を渡します。 c1の色が省略されているか偽造が渡された場合、それは変換されません。
  • 二次機能もグローバルに追加されます。 pSBCrには16進数またはRGB色を渡すことができ、それはこの色情報を含むオブジェクトを返します。その形式は{r:XXX、g:XXX、b:XXX、a:X.XXX}です。 .r.g、および.bの範囲は0から255です。アルファがない場合:.aは-1です。それ以外の場合:.aの範囲は0.000から1.000です。
  • RGB出力の場合、アルファチャンネル付きの色がc0(from)またはc1(to)に渡されると、rgba()よりrgb()が出力されます。
  • マイナーエラーチェックが追加されました。それは完璧ではありません。それはまだクラッシュするか、ぎくしゃくすることができます。しかし、それはいくつかのものをキャッチします。基本的に、構造が何らかの形で誤っている場合、またはパーセンテージが数値ではないか範囲外の場合は、nullが返されます。例:pSBC(0.5,"salt") == null、ここで#saltは有効な色です。 return null;で終わる4行を削除してこの機能を削除し、すばやく小さくします。
  • ログブレンディングを使用します。 Linear Blendingを使用するには、true(4番目のパラメーター)にlを渡します。

コード:

// Version 4.0
const pSBC=(p,c0,c1,l)=>{
    let r,g,b,P,f,t,h,i=parseInt,m=Math.round,a=typeof(c1)=="string";
    if(typeof(p)!="number"||p<-1||p>1||typeof(c0)!="string"||(c0[0]!='r'&&c0[0]!='#')||(c1&&!a))return null;
    if(!this.pSBCr)this.pSBCr=(d)=>{
        let n=d.length,x={};
        if(n>9){
            [r,g,b,a]=d=d.split(","),n=d.length;
            if(n<3||n>4)return null;
            x.r=i(r[3]=="a"?r.slice(5):r.slice(4)),x.g=i(g),x.b=i(b),x.a=a?parseFloat(a):-1
        }else{
            if(n==8||n==6||n<4)return null;
            if(n<6)d="#"+d[1]+d[1]+d[2]+d[2]+d[3]+d[3]+(n>4?d[4]+d[4]:"");
            d=i(d.slice(1),16);
            if(n==9||n==5)x.r=d>>24&255,x.g=d>>16&255,x.b=d>>8&255,x.a=m((d&255)/0.255)/1000;
            else x.r=d>>16,x.g=d>>8&255,x.b=d&255,x.a=-1
        }return x};
    h=c0.length>9,h=a?c1.length>9?true:c1=="c"?!h:false:h,f=pSBCr(c0),P=p<0,t=c1&&c1!="c"?pSBCr(c1):P?{r:0,g:0,b:0,a:-1}:{r:255,g:255,b:255,a:-1},p=P?p*-1:p,P=1-p;
    if(!f||!t)return null;
    if(l)r=m(P*f.r+p*t.r),g=m(P*f.g+p*t.g),b=m(P*f.b+p*t.b);
    else r=m((P*f.r**2+p*t.r**2)**0.5),g=m((P*f.g**2+p*t.g**2)**0.5),b=m((P*f.b**2+p*t.b**2)**0.5);
    a=f.a,t=t.a,f=a>=0||t>=0,a=f?a<0?t:t<0?a:a*P+t*p:0;
    if(h)return"rgb"+(f?"a(":"(")+r+","+g+","+b+(f?","+m(a*1000)/1000:"")+")";
    else return"#"+(4294967296+r*16777216+g*65536+b*256+(f?m(a*255):0)).toString(16).slice(1,f?undefined:-2)
}

使用法:

// Setup:

let color1 = "rgb(20,60,200)";
let color2 = "rgba(20,60,200,0.67423)";
let color3 = "#67DAF0";
let color4 = "#5567DAF0";
let color5 = "#F3A";
let color6 = "#F3A9";
let color7 = "rgb(200,60,20)";
let color8 = "rgba(200,60,20,0.98631)";

// Tests:

/*** Log Blending ***/
// Shade (Lighten or Darken)
pSBC ( 0.42, color1 ); // rgb(20,60,200) + [42% Lighter] => rgb(166,171,225)
pSBC ( -0.4, color5 ); // #F3A + [40% Darker] => #c62884
pSBC ( 0.42, color8 ); // rgba(200,60,20,0.98631) + [42% Lighter] => rgba(225,171,166,0.98631)

// Shade with Conversion (use "c" as your "to" color)
pSBC ( 0.42, color2, "c" ); // rgba(20,60,200,0.67423) + [42% Lighter] + [Convert] => #a6abe1ac

// RGB2Hex & Hex2RGB Conversion Only (set percentage to zero)
pSBC ( 0, color6, "c" ); // #F3A9 + [Convert] => rgba(255,51,170,0.6)

// Blending
pSBC ( -0.5, color2, color8 ); // rgba(20,60,200,0.67423) + rgba(200,60,20,0.98631) + [50% Blend] => rgba(142,60,142,0.83)
pSBC ( 0.7, color2, color7 ); // rgba(20,60,200,0.67423) + rgb(200,60,20) + [70% Blend] => rgba(168,60,111,0.67423)
pSBC ( 0.25, color3, color7 ); // #67DAF0 + rgb(200,60,20) + [25% Blend] => rgb(134,191,208)
pSBC ( 0.75, color7, color3 ); // rgb(200,60,20) + #67DAF0 + [75% Blend] => #86bfd0

/*** Linear Blending ***/
// Shade (Lighten or Darken)
pSBC ( 0.42, color1, false, true ); // rgb(20,60,200) + [42% Lighter] => rgb(119,142,223)
pSBC ( -0.4, color5, false, true ); // #F3A + [40% Darker] => #991f66
pSBC ( 0.42, color8, false, true ); // rgba(200,60,20,0.98631) + [42% Lighter] => rgba(223,142,119,0.98631)

// Shade with Conversion (use "c" as your "to" color)
pSBC ( 0.42, color2, "c", true ); // rgba(20,60,200,0.67423) + [42% Lighter] + [Convert] => #778edfac

// RGB2Hex & Hex2RGB Conversion Only (set percentage to zero)
pSBC ( 0, color6, "c", true ); // #F3A9 + [Convert] => rgba(255,51,170,0.6)

// Blending
pSBC ( -0.5, color2, color8, true ); // rgba(20,60,200,0.67423) + rgba(200,60,20,0.98631) + [50% Blend] => rgba(110,60,110,0.83)
pSBC ( 0.7, color2, color7, true ); // rgba(20,60,200,0.67423) + rgb(200,60,20) + [70% Blend] => rgba(146,60,74,0.67423)
pSBC ( 0.25, color3, color7, true ); // #67DAF0 + rgb(200,60,20) + [25% Blend] => rgb(127,179,185)
pSBC ( 0.75, color7, color3, true ); // rgb(200,60,20) + #67DAF0 + [75% Blend] => #7fb3b9

/*** Other Stuff ***/
// Error Checking
pSBC ( 0.42, "#FFBAA" ); // #FFBAA + [42% Lighter] => null  (Invalid Input Color)
pSBC ( 42, color1, color5 ); // rgb(20,60,200) + #F3A + [4200% Blend] => null  (Invalid Percentage Range)
pSBC ( 0.42, {} ); // [object Object] + [42% Lighter] => null  (Strings Only for Color)
pSBC ( "42", color1 ); // rgb(20,60,200) + ["42"] => null  (Numbers Only for Percentage)
pSBC ( 0.42, "salt" ); // salt + [42% Lighter] => null  (A Little Salt is No Good...)

// Error Check Fails (Some Errors are not Caught)
pSBC ( 0.42, "#salt" ); // #salt + [42% Lighter] => #a5a5a500  (...and a Pound of Salt is Jibberish)

// Ripping
pSBCr ( color4 ); // #5567DAF0 + [Rip] => [object Object] => {'r':85,'g':103,'b':218,'a':0.941}

下の図は、2つのブレンド方法の違いを示しています。


マイクロ機能

本当にスピードとサイズが欲しいのなら、16進数ではなくRGBを使う必要があります。 RGBはより単純でシンプルで、HEXの書き込みは遅すぎて、シンプルな2ライナー(IE、3、4、6、または8桁のHEXコードなど)には多すぎる風味があります。また、いくつかの機能、エラーチェック、HEX2RGB、RGB2HEXを犠牲にする必要があります。同様に、カラーブレンディング数学のために、そしてあなたがシェーディングまたはブレンディングを望むならば、あなたは特定の関数を選ぶ必要があるでしょう(下記のその関数名に基づいて)。これらの関数はアルファチャンネルをサポートします。そして両方の入力カラーがアルファを持っているとき、それはそれらを線形にブレンドします。 2色のうち1色だけにアルファがある場合は、結果の色までそのまま通過します。以下は、非常に速くて小さい2つの線形関数です。

const RGB_Linear_Blend=(p,c0,c1)=>{
    var i=parseInt,r=Math.round,P=1-p,[a,b,c,d]=c0.split(","),[e,f,g,h]=c1.split(","),x=d||h,d=x?","+(!d?h:!h?d:r((parseFloat(d)*P+parseFloat(h)*p)*1000)/1000+")"):")";
    return"rgb"+(x?"a(":"(")+r(i(a[3]=="a"?a.slice(5):a.slice(4))*P+i(e[3]=="a"?e.slice(5):e.slice(4))*p)+","+r(i(b)*P+i(f)*p)+","+r(i(c)*P+i(g)*p)+d;
}

const RGB_Linear_Shade=(p,c)=>{
    var i=parseInt,r=Math.round,[a,b,c,d]=c.split(","),P=p<0,t=P?0:255*p,P=P?1+p:1-p;
    return"rgb"+(d?"a(":"(")+r(i(a[3]=="a"?a.slice(5):a.slice(4))*P+t)+","+r(i(b)*P+t)+","+r(i(c)*P+t)+(d?","+d:")");
}

const RGB_Log_Blend=(p,c0,c1)=>{
    var i=parseInt,r=Math.round,P=1-p,[a,b,c,d]=c0.split(","),[e,f,g,h]=c1.split(","),x=d||h,d=x?","+(!d?h:!h?d:r((parseFloat(d)*P+parseFloat(h)*p)*1000)/1000+")"):")";
    return"rgb"+(x?"a(":"(")+r((P*i(a[3]=="a"?a.slice(5):a.slice(4))**2+p*i(e[3]=="a"?e.slice(5):e.slice(4))**2)**0.5)+","+r((P*i(b)**2+p*i(f)**2)**0.5)+","+r((P*i(c)**2+p*i(g)**2)**0.5)+d;
}

const RGB_Log_Shade=(p,c)=>{
    var i=parseInt,r=Math.round,[a,b,c,d]=c.split(","),P=p<0,t=P?0:p*255**2,P=P?1+p:1-p;
    return"rgb"+(d?"a(":"(")+r((P*i(a[3]=="a"?a.slice(5):a.slice(4))**2+t)**0.5)+","+r((P*i(b)**2+t)**0.5)+","+r((P*i(c)**2+t)**0.5)+(d?","+d:")");
}

もっと情報が欲しい? github で全文を読む。

PT

(P.s.他の混合方法の数学を知っている人はいてください。)

832
Pimp Trizkit

私はとてもうまくいく解決策を私に作りました:

function shadeColor(color, percent) {

    var R = parseInt(color.substring(1,3),16);
    var G = parseInt(color.substring(3,5),16);
    var B = parseInt(color.substring(5,7),16);

    R = parseInt(R * (100 + percent) / 100);
    G = parseInt(G * (100 + percent) / 100);
    B = parseInt(B * (100 + percent) / 100);

    R = (R<255)?R:255;  
    G = (G<255)?G:255;  
    B = (B<255)?B:255;  

    var RR = ((R.toString(16).length==1)?"0"+R.toString(16):R.toString(16));
    var GG = ((G.toString(16).length==1)?"0"+G.toString(16):G.toString(16));
    var BB = ((B.toString(16).length==1)?"0"+B.toString(16):B.toString(16));

    return "#"+RR+GG+BB;
}

例を明るくする:

shadeColor("#63C6FF",40);

暗くする例:

shadeColor("#63C6FF",-40);
90
Pablo

これは私があなたの機能に基づいて使ったものです。私は直感的に理解できるので、パーセンテージを超えるステップを使用することを好みます。

たとえば、200ブルーの値の20%は、40ブルーの値の20%と大きく異なります。

とにかく、これが私の修正です。あなたのオリジナル機能のおかげです。

function adjustBrightness(col, amt) {

    var usePound = false;

    if (col[0] == "#") {
        col = col.slice(1);
        usePound = true;
    }

    var R = parseInt(col.substring(0,2),16);
    var G = parseInt(col.substring(2,4),16);
    var B = parseInt(col.substring(4,6),16);

    // to make the colour less bright than the input
    // change the following three "+" symbols to "-"
    R = R + amt;
    G = G + amt;
    B = B + amt;

    if (R > 255) R = 255;
    else if (R < 0) R = 0;

    if (G > 255) G = 255;
    else if (G < 0) G = 0;

    if (B > 255) B = 255;
    else if (B < 0) B = 0;

    var RR = ((R.toString(16).length==1)?"0"+R.toString(16):R.toString(16));
    var GG = ((G.toString(16).length==1)?"0"+G.toString(16):G.toString(16));
    var BB = ((B.toString(16).length==1)?"0"+B.toString(16):B.toString(16));

    return (usePound?"#":"") + RR + GG + BB;

}
4
Eric Sloan

あなたはrgb> hsl変換について考えましたか?それからルミノシティを上下に動かすだけ?それが私のやり方です。

いくつかのアルゴリズムをちょっと見てみると、私は以下のサイトを手に入れた。

PHP: http://serennu.com/colour/rgbtohsl.php

Javascript: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-alversions-in-javascript

EDIT上記のリンクは無効になりました。あなたは ページソース または 要旨 のgit hubを見ることができます。

あるいは、別のStackOverflow の質問 を見てみるのもいいでしょう。


これはOPにとって正しい選択ではありませんが、以下は私が最初に提案していたコードの近似です。 (rgb/hsl変換関数があるとします)

var SHADE_SHIFT_AMOUNT = 0.1; 

function lightenShade(colorValue)
{
    if(colorValue && colorValue.length >= 6)
    {
        var redValue = parseInt(colorValue.slice(-6,-4), 16);
        var greenValue = parseInt(colorValue.slice(-4,-2), 16);
        var blueValue = parseInt(colorValue.slice(-2), 16);

        var hsl = rgbToHsl(redValue, greenValue, blueValue);
        hsl[2]= Math.min(hsl[2] + SHADE_SHIFT_AMOUNT, 1);
        var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
        return "#" + rgb[0].toString(16) + rgb[1].toString(16) + rgb[2].toString(16);
    }
    return null;
}

function darkenShade(colorValue)
{
    if(colorValue && colorValue.length >= 6)
    {
        var redValue = parseInt(colorValue.slice(-6,-4), 16);
        var greenValue = parseInt(colorValue.slice(-4,-2), 16);
        var blueValue = parseInt(colorValue.slice(-2), 16);

        var hsl = rgbToHsl(redValue, greenValue, blueValue);
        hsl[2]= Math.max(hsl[2] - SHADE_SHIFT_AMOUNT, 0);
        var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
        return "#" + rgb[0].toString(16) + rgb[1].toString(16) + rgb[2].toString(16);
    }
    return null;
}

これを仮定します。

  1. hslToRgbrgbToHslという関数があります。
  2. パラメータcolorValueは、#RRGGBBの形式の文字列です。

CSSについて説明しているのであれば、IE9/Chrome/Firefox用に hsl/hsla を指定するための構文があります。

4
James Khoury

私はあなたの関数を試してみましたが、ちょっとしたバグがありました。もしある最終的な 'r'値が1桁だけの場合、正しい値が '0a0a0a'の場合、結果は 'a0a0a'のようになります。私はあなたの返品の代わりにこれを追加することによってそれを素早く修正しました:

var rStr = (r.toString(16).length < 2)?'0'+r.toString(16):r.toString(16);
var gStr = (g.toString(16).length < 2)?'0'+g.toString(16):g.toString(16);
var bStr = (b.toString(16).length < 2)?'0'+b.toString(16):b.toString(16);

return (usePound?"#":"") + rStr + gStr + bStr;

たぶんそれはそんなに素敵ではないがそれは仕事をする。偉大な機能、ところで。必要なものだけ。 :)

4
Cool Acid

エリックの答えに基づいた超シンプルなワンライナー

function adjust(color, amount) {
    return '#' + color.replace(/^#/, '').replace(/../g, color => ('0'+Math.min(255, Math.max(0, parseInt(color, 16) + amount)).toString(16)).substr(-2));
}

例:

adjust('#ffffff', -20) => "#ebebeb"
adjust('000000', 20) => "#141414"
2
supersan

色を特定の明るさレベルに変更したい - 色が以前の明るさに関係なく - これはうまくいくように思われる単純なJS関数です、私はそれがもっと短いかもしれないと確信していますが

function setLightPercentage(col: any, p: number) {
    const R = parseInt(col.substring(1, 3), 16);
    const G = parseInt(col.substring(3, 5), 16);
    const B = parseInt(col.substring(5, 7), 16);
    const curr_total_dark = (255 * 3) - (R + G + B);

    // calculate how much of the current darkness comes from the different channels
    const RR = ((255 - R) / curr_total_dark);
    const GR = ((255 - G) / curr_total_dark);
    const BR = ((255 - B) / curr_total_dark);

    // calculate how much darkness there should be in the new color
    const new_total_dark = ((255 - 255 * (p / 100)) * 3);

    // make the new channels contain the same % of available dark as the old ones did
    const NR = 255 - Math.round(RR * new_total_dark);
    const NG = 255 - Math.round(GR * new_total_dark);
    const NB = 255 - Math.round(BR * new_total_dark);

    const RO = ((NR.toString(16).length === 1) ? "0" + NR.toString(16) : NR.toString(16));
    const GO = ((NG.toString(16).length === 1) ? "0" + NG.toString(16) : NG.toString(16));
    const BO = ((NB.toString(16).length === 1) ? "0" + NB.toString(16) : NB.toString(16));

    return "#" + RO + GO + BO;}
2

次の方法では、16進数(Hex)カラー文字列の露出値を明るくしたり暗くしたりできます。

private static string GetHexFromRGB(byte r, byte g, byte b, double exposure)
{
    exposure = Math.Max(Math.Min(exposure, 1.0), -1.0);
    if (exposure >= 0)
    {
        return "#"
            + ((byte)(r + ((byte.MaxValue - r) * exposure))).ToString("X2")
            + ((byte)(g + ((byte.MaxValue - g) * exposure))).ToString("X2")
            + ((byte)(b + ((byte.MaxValue - b) * exposure))).ToString("X2");
    }
    else
    {
        return "#"
            + ((byte)(r + (r * exposure))).ToString("X2")
            + ((byte)(g + (g * exposure))).ToString("X2")
            + ((byte)(b + (b * exposure))).ToString("X2");
    }

}

GetHexFromRGB()の最後のパラメータ値に、-1と1の間のどこかにdouble値を渡します(-1は黒、0は変更されず、1は白)。

// split color (#e04006) into three strings
var r = Convert.ToByte("e0", 16);
var g = Convert.ToByte("40", 16);
var b = Convert.ToByte("06", 16);

GetHexFromRGB(r, g, b, 0.25);  // Lighten by 25%;
1
Jason Williams

C#バージョン...#FF12AE34という形式のカラー文字列を取得しているので、#FFを切り取る必要があります。

    private string GetSmartShadeColorByBase(string s, float percent)
    {
        if (string.IsNullOrEmpty(s))
            return "";
        var r = s.Substring(3, 2);
        int rInt = int.Parse(r, NumberStyles.HexNumber);
        var g = s.Substring(5, 2);
        int gInt = int.Parse(g, NumberStyles.HexNumber);
        var b = s.Substring(7, 2);
        int bInt = int.Parse(b, NumberStyles.HexNumber);

        var t = percent < 0 ? 0 : 255;
        var p = percent < 0 ? percent*-1 : percent;

        int newR = Convert.ToInt32(Math.Round((t - rInt) * p) + rInt);
        var newG = Convert.ToInt32(Math.Round((t - gInt) * p) + gInt);
        var newB = Convert.ToInt32(Math.Round((t - bInt) * p) + bInt);

        return String.Format("#{0:X2}{1:X2}{2:X2}", newR, newG, newB);
    }
1
user1618171

私はそのjQueryの依存関係を削除するために優れたxcolorライブラリを移植しました。色を明るくしたり暗くしたりするなど、そこにはたくさんの機能があります。

実際、16進数をRGBに変換することは、色を明るくしたり暗くしたりすることとはまったく別の機能です。 DRYをお願いします。どのような場合でも、RGBカラーを取得したら、必要な明るさとあなたが持っている明るさの差を、それぞれのRGB値に加えることができます。

var lightness = function(level) {
    if(level === undefined) {
        return Math.max(this.g,this.r,this.b)
    } else {
        var roundedLevel = Math.round(level) // fractions won't work here
        var levelChange = roundedLevel - this.lightness()

        var r = Math.max(0,this.r+levelChange)
        var g = Math.max(0,this.g+levelChange)
        var b = Math.max(0,this.b+levelChange)

        if(r > 0xff) r = 0xff
        if(g > 0xff) g = 0xff
        if(b > 0xff) b = 0xff

        return xolor({r: r, g: g, b: b})
    }
}

var lighter = function(amount) {
    return this.lightness(this.lightness()+amount)
}

ソースの詳細については、 https://github.com/fresheneesz/xolor を参照してください。

0
B T

PHPで簡単に色を濃くするには?

<?php
function shadeColor ($color='#cccccc', $percent=-25) {

  $color = Str_Replace("#",Null,$color);

  $r = Hexdec(Substr($color,0,2));
  $g = Hexdec(Substr($color,2,2));
  $b = Hexdec(Substr($color,4,2));

  $r = (Int)($r*(100+$percent)/100);
  $g = (Int)($g*(100+$percent)/100);
  $b = (Int)($b*(100+$percent)/100);

  $r = Trim(Dechex(($r<255)?$r:255));  
  $g = Trim(Dechex(($g<255)?$g:255));  
  $b = Trim(Dechex(($b<255)?$b:255));

  $r = ((Strlen($r)==1)?"0{$r}":$r);
  $g = ((Strlen($g)==1)?"0{$g}":$g);
  $b = ((Strlen($b)==1)?"0{$b}":$b);

  return (String)("#{$r}{$g}{$b}");
}

echo shadeColor(); // #999999
0
jsebestyan

私は長い間色合い/色合いを作り出すことができることを望んでいました、これが私のJavaScriptソリューションです:

const varyHue = function (hueIn, pcIn) {
    const truncate = function (valIn) {
        if (valIn > 255) {
            valIn = 255;
        } else if (valIn < 0)  {
            valIn = 0;
        }
        return valIn;
    };

    let red   = parseInt(hueIn.substring(0, 2), 16);
    let green = parseInt(hueIn.substring(2, 4), 16);
    let blue  = parseInt(hueIn.substring(4, 6), 16);
    let pc    = parseInt(pcIn, 10);    //shade positive, tint negative
    let max   = 0;
    let dif   = 0;

    max = red;

    if (pc < 0) {    //tint: make lighter
        if (green < max) {
            max = green;
        }

        if (blue < max) {
            max = blue;
        }

        dif = parseInt(((Math.abs(pc) / 100) * (255 - max)), 10);

        return leftPad(((truncate(red + dif)).toString(16)), '0', 2)  + leftPad(((truncate(green + dif)).toString(16)), '0', 2) + leftPad(((truncate(blue + dif)).toString(16)), '0', 2);
    } else {    //shade: make darker
        if (green > max) {
            max = green;
        }

        if (blue > max) {
            max = blue;
        }

        dif = parseInt(((pc / 100) * max), 10);

        return leftPad(((truncate(red - dif)).toString(16)), '0', 2)  + leftPad(((truncate(green - dif)).toString(16)), '0', 2) + leftPad(((truncate(blue - dif)).toString(16)), '0', 2);
    }
};
0
user2655360