क्रमिक रूप से हल्का या गहरा एक हेक्स रंग (या आरजीबी, और ब्लेंड रंग)


503

यहां एक फ़ंक्शन है जिसे मैं प्रोग्रामिक रूप से हल्का करने या एक विशिष्ट राशि द्वारा एक हेक्स रंग को गहरा करने के लिए काम कर रहा था। बस एक स्ट्रिंग "3F6D2A"में रंग ( col) और एक बेस 10 पूर्णांक ( 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);
}


// TEST
console.log( LightenDarkenColor("3F6D2A",40) );

विकास के उपयोग के लिए यहाँ एक आसान संस्करण पढ़ें:

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


// TEST
console.log(LightenDarkenColor("3F6D2A", -40));

और अंत में रंगों को संभालने के लिए एक संस्करण जो शुरुआत में "#" हो सकता है या नहीं हो सकता है। प्लस अनुचित रंग मूल्यों के लिए समायोजन:

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

ठीक है, तो अब यह सिर्फ एक दो पंक्तियाँ नहीं है, बल्कि यह बहुत सरल है और यदि आप "#" का उपयोग नहीं कर रहे हैं और रंगों की सीमा से बाहर जाँच करने की आवश्यकता नहीं है, तो यह केवल कुछ पंक्तियाँ हैं।

यदि "#" का उपयोग नहीं कर रहे हैं, तो आप इसे कोड में जोड़ सकते हैं जैसे:

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

मुझे लगता है कि मेरा मुख्य सवाल यह है कि क्या मैं यहां ठीक हूं? क्या यह कुछ (सामान्य) स्थितियों को शामिल नहीं करता है?


1
यदि आपको रंगों को संशोधित करते समय अपेक्षित परिणाम नहीं मिलते हैं, तो मेरा सुझाव है कि LAB रंग स्थान की तलाश करें, जो मानवीय दृष्टि के करीब हो। कई भाषाओं में रूपांतरण के लिए पुस्तकालय हैं। मेरे अनुभव में विशेष रूप से नारंगी के रंग काला या हल्का होने पर समस्याग्रस्त हो सकते हैं।
हेनरिक

बहुत अच्छी बात है। हालांकि, इस सवाल का मुख्य उद्देश्य सबसे पहले, सबसे तेज़ रनटाइम और सबसे छोटे आकार का सूत्र ढूंढना था ... और दूसरा, इसकी सटीकता। इसलिए, मैंने एचएसएल या जो भी हो, उसे परिवर्तित करने का सौदा क्यों नहीं किया। यहां गति और आकार अधिक महत्वपूर्ण हैं। लेकिन, जैसा कि आप सूत्र के मेरे संस्करण 2 के साथ देख सकते हैं। LERP से शेड का उपयोग करने से छाया रेंज के माध्यम से सुखद संतरे निकलेंगे। नीचे दिए गए रंग चार्ट पर एक नज़र डालें और मुझे बताएं कि क्या वह छाया सीमा वास्तविक सटीक के करीब नहीं है।
पिंप ट्राइज़किट

मैं यहाँ संरचना के साथ थोड़ा भ्रमित हो गया, लेकिन आप सही हैं, shadeColor1 के लिए नारंगी का स्तर बहुत अच्छा लगता है।
हेनरिक

योग्य, आपका मतलब है shadeColor2। मुझे लगता है कि आप जिस संरचना के बारे में बात कर रहे हैं, वह उत्तर का समग्र लेआउट है? अधिक स्पष्ट करने के लिए कोई संकेत?
पिंप ट्राइज़किट

3
# उपरोक्त के साथ फ़ंक्शन में सिर्फ एक समस्या है कि यह अंतिम शून्य कोड zeroes के साथ शुरू होने पर अग्रणी शून्य नहीं बनाता है। उदाहरण के लिए, यदि हेक्स कोड # 00a6b7 है तो यह इसे # a6b7 के रूप में आउटपुट करेगा, जो कि css के रूप में उपयोग करने पर काम नहीं करेगा। आप इसे इसके द्वारा रिटर्न लाइन को बदलकर सही कर सकते हैं: var string = "000000" + (g | (b << 8) | | (r << 16)) .String (16); वापसी (usePound; "#": "") + string.substr (string.length-6);
राफेल लेवी

जवाबों:


876

खैर, यह जवाब इसका अपना जानवर बन गया है। कई नए संस्करण, यह लंबे समय से बेवकूफ हो रहा था। इस उत्तर के लिए सभी महान योगदानकर्ताओं को बहुत धन्यवाद। लेकिन, जनता के लिए इसे सरल बनाए रखने के लिए। मैंने इस उत्तर के विकास के सभी संस्करणों / इतिहास को अपने गिथब में संग्रहीत किया । और इसे स्टैकऑवरफ्लो पर सबसे नए संस्करण के साथ यहां साफ करना शुरू किया। इस संस्करण के लिए माइक 'पोमैक्स' कमरमन्स के लिए एक विशेष धन्यवाद निकलता है । उसने मुझे नया गणित दिया।


यह फ़ंक्शन ( pSBC) एक HEX या RGB वेब रंग लेगा।pSBCइसे गहरा या हल्का शेड कर सकते हैं, या इसे दूसरे रंग के साथ मिश्रित कर सकते हैं, और इसे सही थ्रू भी पास कर सकते हैं लेकिन हेक्स से RGB (Hex2RGB) या RGB से Hex (RGB2Hex) में परिवर्तित कर सकते हैं। आप सब भी बिना यह जाने कि आप किस रंग प्रारूप का उपयोग कर रहे हैं।

यह वास्तव में तेजी से चलता है, शायद सबसे तेज, विशेष रूप से इसकी कई विशेषताओं को देखते हुए। इसे बनाने में काफी समय लगा था। पूरी कहानी मेरे गितुब पर देखें । यदि आप छाया या मिश्रण के लिए सबसे छोटा और तेज़ संभव तरीका चाहते हैं, तो नीचे दिए गए माइक्रो फ़ंक्शंस देखें और 2-लाइनर स्पीड राक्षसों में से एक का उपयोग करें। वे गहन एनिमेशन के लिए महान हैं, लेकिन यहां यह संस्करण अधिकांश एनिमेशन के लिए काफी तेज है।

यह फ़ंक्शन लॉग ब्लेंडिंग या रैखिक सम्मिश्रण का उपयोग करता है। हालाँकि, यह ठीक से हल्का या गहरा रंग करने के लिए HSL में परिवर्तित नहीं होता है। इसलिए, इस फ़ंक्शन के परिणाम उन बहुत बड़े और बहुत धीमे कार्यों से भिन्न होंगे जो एचएसएल का उपयोग करते हैं।

pSBC के साथ jsFiddle

github> pSBC विकी

विशेषताएं:

  • स्ट्रिंग्स के रूप में मानक हेक्स रंगों को ऑटो-डिटेक्ट करता है और स्वीकार करता है। उदाहरण के लिए: "#AA6622"या "#bb551144"
  • स्ट्रिंग्स के रूप में मानक आरजीबी रंगों को ऑटो-डिटेक्ट करता है और स्वीकार करता है। उदाहरण के लिए: "rgb(123,45,76)"या"rgba(45,15,74,0.45)"
  • रंग सफेद या काले रंग के प्रतिशत के अनुसार।
  • रंगों को एक साथ प्रतिशत से रंगता है।
  • क्या Hex2RGB और RGB2Hex एक ही समय में रूपांतरण करते हैं, या एकल।
  • #RGB (या #RGBA) फॉर्म में 3 अंकों (या 4 अंकों w / अल्फा) HEX रंग कोड को स्वीकार करता है। यह उनका विस्तार करेगा। उदाहरण के लिए: "#C41"बन जाता है"#CC4411"
  • स्वीकार और (रैखिक) अल्फा चैनलों को मिश्रित करता है। यदि या तो c0(से) रंग या c1(से) रंग में एक अल्फा चैनल है, तो लौटे रंग में एक अल्फा चैनल होगा। यदि दोनों रंगों में एक अल्फा चैनल है, तो दिए गए रंग दिए गए प्रतिशत का उपयोग करके दो अल्फा चैनलों का एक रैखिक मिश्रण होगा (जैसे कि यह एक सामान्य रंग चैनल था)। यदि केवल दो रंगों में से एक में एक अल्फा चैनल है, तो यह अल्फा केवल दिए गए रंग के माध्यम से पारित हो जाएगा। यह पारदर्शिता के स्तर को बनाए रखते हुए पारदर्शी रंग को मिश्रित / शेड करने की अनुमति देता है। या, यदि पारदर्शिता के स्तर के साथ-साथ मिश्रण होना चाहिए, तो सुनिश्चित करें कि दोनों रंगों में अल्फ़ाज़ हैं। छायांकन करते समय, यह अल्फा चैनल को सीधे थ्रू पास करेगा। यदि आप बेसिक शेडिंग चाहते हैं जो अल्फा चैनल को भी शेड करता है, तो उपयोग करें rgb(0,0,0,1)याrgb(255,255,255,1) अपने रूप मेंc1(से) रंग (या उनके हेक्स समकक्ष)। RGB रंगों के लिए, दिए गए रंग का अल्फा चैनल 3 दशमलव स्थानों पर गोल होगा।
  • सम्मिश्रण का उपयोग करते समय RGB2Hex और Hex2RGB रूपांतरण निहित हैं। c0रंग के बावजूद (से); लौटाया रंग हमेशा रंग के प्रारूप में c1(से) रंग का होगा, यदि कोई मौजूद है। यदि कोई c1() रंग नहीं है, तो रंग के 'c'रूप में पास करें c1और यह जो भी c0रंग है उसे छाया देगा और परिवर्तित करेगा । यदि रूपांतरण केवल वांछित है, तो 0प्रतिशत ( p) के रूप में अच्छी तरह से पास करें। यदि c1रंग छोड़ा गया है या एक गैर- stringमें पारित किया गया है, तो यह रूपांतरित नहीं होगा।
  • एक द्वितीयक कार्य को वैश्विक रूप से भी जोड़ा जाता है। pSBCrएक हेक्स या आरजीबी रंग पारित किया जा सकता है और यह इस रंग की जानकारी युक्त एक वस्तु देता है। इसके रूप में: {r: XXX, g: XXX, b: XXX, a: X.XXX}। कहाँ .r, .gऔर .b0 से 255 तक है। और जब कोई अल्फा नहीं है: .a-1 है। अन्यथा: .aसीमा 0.000 से 1.000 है।
  • आरजीबी आउटपुट के लिए, यह तब rgba()खत्म rgb()हो जाता है जब एक अल्फा चैनल के साथ एक रंग c0() और / या c1( ) से पारित किया गया था ।
  • मामूली त्रुटि जाँच जोड़ी गई है। यह सही नहीं है। यह अभी भी क्रैश कर सकता है या जीब्रीश बना सकता है। लेकिन यह कुछ सामान पकड़ लेगा। मूल रूप से, यदि संरचना कुछ मायनों में गलत है या यदि प्रतिशत संख्या या दायरे से बाहर नहीं है, तो यह वापस आ जाएगा null। एक उदाहरण: pSBC(0.5,"salt") == nullजहां यह सोचता #saltहै कि एक वैध रंग है। return null;इस सुविधा को हटाने के लिए समाप्त होने वाली चार पंक्तियों को हटा दें और इसे तेज़ और छोटा करें।
  • लॉग सम्मिश्रण का उपयोग करता है। दर्रा trueके लिए में lरैखिक सम्मिश्रण का उपयोग करने (4 पैरामीटर)।

कोड:

// 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=this.pSBCr(c0),P=p<0,t=c1&&c1!="c"?this.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}

नीचे दी गई तस्वीर दो सम्मिश्रण विधियों में अंतर दिखाने में मदद करेगी:


सूक्ष्म कार्य

यदि आप वास्तव में गति और आकार चाहते हैं, तो आपको RGB नहीं HEX का उपयोग करना होगा। RGB अधिक सीधा और सरल है, HEX बहुत धीमा लिखता है और एक साधारण टू-लाइनर (IE के लिए बहुत सारे फ्लेवर में आता है। यह 3, 4, 6 या 8 अंकों का HEX कोड हो सकता है)। आपको कुछ सुविधाओं, कोई त्रुटि जाँच, कोई HEX2RGB और न ही RGB2HEX का त्याग करने की आवश्यकता होगी। साथ ही, आपको रंग सम्मिश्रण गणित के लिए एक विशिष्ट फ़ंक्शन (नीचे इसके फ़ंक्शन नाम के आधार पर) का चयन करना होगा, और यदि आप छायांकन या सम्मिश्रण चाहते हैं। ये फ़ंक्शन अल्फा चैनल का समर्थन करते हैं। और जब दोनों इनपुट रंगों में अल्फ़ाज़ होते हैं तो यह उन्हें ब्लेंड कर देगा। यदि केवल दो रंगों में से एक में एक अल्फा है, तो यह परिणामी रंग के साथ सीधे गुजरता है। नीचे दो लाइनर फ़ंक्शन हैं जो अविश्वसनीय रूप से तेज़ और छोटे हैं:

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,j=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)+j;
}

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,j=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)+j;
}

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:")");
}

अधिक जानकारी चाहते हैं? पर पूरा writeup पढ़ें GitHub

पीटी

(यदि किसी के पास अन्य सम्मिश्रण विधि के लिए गणित है, तो कृपया साझा करें।)


8
जिन लोगों को इसकी ज़रूरत है उनके लिए एक PHP संस्करण: gist.github.com/chaoszcat/5325115#file-gistfile1-php
Lionel Chan

27
मैंने tinycolor.darken(color,amount);
एफडब्ल्यूएनआरएन

4
शानदार पोस्ट ... :) ... बस इसका स्विफ्ट एक्सटेंशन बनाया गया है: gist.github.com/matejukmar/1da47f7a950d1ba68a95
Matej Ukmar

2
यहाँ अद्यतन किए गए shadeColor2 संस्करण के लिए PHP संस्करण है: function shadeColor2($color, $percent) { $color = str_replace("#", "", $color); $t=$percent<0?0:255; $p=$percent<0?$percent*-1:$percent; $RGB = str_split($color, 2); $R=hexdec($RGB[0]); $G=hexdec($RGB[1]); $B=hexdec($RGB[2]); return '#'.substr(dechex(0x1000000+(round(($t-$R)*$p)+$R)*0x10000+(round(($t-$G)*$p)+$G)*0x100+(round(($t-$B)*$p)+$B)),1); }
केविन एम

2
क्षमा करें, मैंने स्पष्ट रूप से उस बिंदु को याद किया। शायद दो कारण हैं। पहला और स्पष्ट है कि मैं Math.Round का उपयोग करता हूं और आपको सटीक रंग के लिए दशमलव संख्याओं का उपयोग करने की आवश्यकता नहीं है (रंग हेक्स में दशमलव नहीं हैं)। उदाहरण के लिए, यदि रेड चैनल है 8, 10%तो आप जोड़ सकते हैं 8.8कि कौन सा दौर है 9। फिर 9.09%दूर ले जाओ 9और तुम जाओ 8.1819। कौन सा करने के लिए राउंड 8ताकि एक बुरा उदाहरण है। लेकिन यह अभी भी दिखाता है कि आप ले जा रहे हैं 9.09%की 9नहीं और 8.8। तो वहाँ कुछ संख्याएँ हो सकती हैं जो मेरे उदाहरण के समान ही वापस न हों।
पिंप ट्रीज़िटक

121

मैंने एक समाधान बनाया जो मेरे लिए बहुत अच्छा काम करता है:

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

4
अच्छा, मुझे प्रतिशत पसंद है! +1 थू, मैं R = ((R<255)?R:255).toString(16);तब R = R.length==1 ? "0"+R : Rगति के लिए करूँगा । और im यकीन है कि toUpperCase की बात नहीं है?
पिंप ट्राइज़किट

यह अनावश्यक है। मैं केवल परीक्षण के दौरान सुंदर प्रिंट के लिए इसे जोड़ता हूं। मैं उसे संपादित करूंगा।
पाब्लो

बहुत अच्छा। हालांकि, क्या 100% लाइटर पूरी तरह से सफेद नहीं होना चाहिए और 100% अंधेरा हमेशा काला होना चाहिए, कोई फर्क नहीं पड़ता कि क्या रंग है? ऐसा लगता है -100 किसी भी रंग को काला बनाता है, लेकिन 100 (सकारात्मक) इसे पूरी तरह से सफेद नहीं बनाता है।
केविन एम

4
# ff0000, # 00ff00, # 0000ff
Hitori

इसे काले रंग के साथ काम करने के लिए मैंने सिर्फ यह हैक किया var R = parseInt(color.substring(1, 3), 16) var G = parseInt(color.substring(3, 5), 16) var B = parseInt(color.substring(5, 7), 16) if (R == 0) R = 32; if (G == 0) G = 32; if (B == 0) B = 32;
इरफान रज़ा

20

एरिक के जवाब पर आधारित एक सुपर सिंपल वन लाइनर है

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"

7
"सुपर सरल"।
एंड्रयू

5

यह वही है जो मैंने आपके फ़ंक्शन के आधार पर उपयोग किया था। मैं प्रतिशत से अधिक चरणों का उपयोग करना पसंद करता हूं क्योंकि यह मेरे लिए अधिक सहज है।

उदाहरण के लिए, 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

मैंने आपके फ़ंक्शन की कोशिश की और थोड़ा बग था: यदि कुछ अंतिम 'r' मान केवल 1 अंक है, तो परिणाम कुछ इस तरह आता है: 'a0a0a' जब सही मान '0a0a0a' होता है, उदाहरण के लिए। मैंने आपकी वापसी के बजाय इसे जोड़कर इसे शीघ्रता से ठीक किया:

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;

शायद यह इतना अच्छा नहीं है लेकिन यह काम करता है। शानदार समारोह, BTW। मुझे जिस चीज की जरूरत थी। :)


1
डिबग और प्रशंसा के लिए धन्यवाद! बहुत बुरा इसका जवाब नहीं है कि क्या कोई तेज़ तरीका है या नहीं, जो मेरा मुख्य प्रश्न है। संभवतः सभी हेक्स और कोई आधार रूपांतरण का उपयोग कर एक। थियो, मुझे लगता है कि आपने मुझे बताया था कि क्या मेरे पास सही कोड (+1) है। दुर्भाग्य से, ठीक काफी अधिक भूमि के ऊपर (अब अपनी बुला toString 6 बार) जोड़ा, और थोड़ा कम KISS। हो सकता है कि आधार 16 रूपांतरण से पहले यह जांचना तेज़ हो कि आधार संख्या 15 या उससे कम है या नहीं। लेकिन मुझे पसंद है!
पिंप ट्राइज़किट

4

क्या आपने rgb> hsl रूपांतरण के बारे में सोचा है? तो बस ऊपर और नीचे Luminosity स्थानांतरित? जिस तरह से मैं जाऊँगा।

कुछ एल्गोरिदम के लिए एक त्वरित नज़र मुझे निम्नलिखित साइटें मिलीं।

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

जावास्क्रिप्ट: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript

उपरोक्त लिंक को संपादित करना अब मान्य नहीं है। आप पृष्ठ स्रोत या जिस्ट के लिए git हब देख सकते हैं

वैकल्पिक रूप से एक और StackOverflow प्रश्न देखने के लिए एक अच्छी जगह हो सकती है।


भले ही यह ओपी के लिए सही विकल्प नहीं है लेकिन निम्नलिखित कोड का एक अनुमान है जो मैं मूल रूप से सुझा रहा था। (मान लें कि आपके पास आरजीबी / एचएसएल रूपांतरण कार्य हैं)

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. आपके पास कार्य हैं hslToRgbऔरrgbToHsl
  2. पैरामीटर #RRGGBBcolorValue के रूप में एक स्ट्रिंग है

हालाँकि अगर हम css पर चर्चा कर रहे हैं तो IE9 / Chrome / Firefox के लिए hsl / hsla को निर्दिष्ट करने के लिए एक सिंटैक्स है ।


दिलचस्प है, लेकिन तब मुझे हेक्स स्ट्रिंग से आरजीबी में एचएसएल में परिवर्तित नहीं करना होगा? इसकी अधिक जटिल की तरह लगता है। शायद मुझे कुछ याद आ रहा है। लेकिन, मुझे संभव (निष्पादन समय) के रूप में एक KISS तरह से यह करने के लिए देख रहा हूँ, साथ ही तेजी से। मुझे आदर्श लगता है, अगर मैं यह सब हेक्स में कर सकता हूं जो सबसे तेज होगा। लेकिन, मैंने यहां जो समाधान विकसित किया है, उसमें वृद्धिशील राशि जोड़ने में सक्षम होने के लिए आरजीबी शामिल है।
पिंप ट्राइज़किट

हाँ, मुझे लगता है कि यह धीमा, अधिक जटिल होगा और यदि आप आरजीबी का उपयोग एचएसएल रूपांतरण में कहीं और नहीं करते हैं तो यह संभवतः सबसे सरल समाधान नहीं होगा। हालाँकि, यह आरजीबी मूल्यों को जोड़ने की तुलना में अधिक सटीक होगा, हालांकि मैं खुद एक रंग व्यक्ति नहीं हूं। यह सब इस बात पर निर्भर करता है कि आप कितना सही अनुमान लगाना चाहते हैं।
जेम्स खुर्री

आपके द्वारा बताई गई सटीकता की हानि क्या है? मुझे लगता है कि आप सभी [वेब] रंग आरजीबी या कुछ के साथ उपलब्ध नहीं हैं?
पिंप ट्राइज़किट

जैसा कि मैंने कहा कि मुझे रंग के बारे में इतना नहीं पता है: विकी कलर थ्योरी
जेम्स खुर्री

@Pimp Trizkit: यह कम सटीक है क्योंकि (और यह सिर्फ मेरा सिद्धांत है ... मैं रंग विशेषज्ञ नहीं हूं) आप प्रत्येक चैनल को समान राशि में स्थानांतरित कर रहे हैं, फिर चाहे उस रंग की कितनी भी शुरुआत क्यों न हो। मुझे लगता है कि इससे संतृप्ति कम हो जाएगी क्योंकि आप चैनलों को एक-दूसरे के करीब ला रहे हैं (प्रतिशत के हिसाब से)। बेशक, अगर आप अतिप्रवाह / कमप्रवाह है जो वैसे भी अपरिहार्य है।
मैथ्यू क्रुमले

2

सी # संस्करण ... ध्यान दें कि मुझे इस प्रारूप # 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);
    }

5
पहले कभी भी C # का उपयोग नहीं किया गया था, लेकिन ऐसा लगता है कि पिछले तीन वैरिएंट डिक्लेयर किए गए हैं। एक intऔर दो varsप्रकार के डेटा के लिए।
पिंप ट्राइजकिट

4
C # में var कीवर्ड का अर्थ है कि कंपाइलर को कंपाइल समय पर टाइप करने दिया जाए। तो int और var के ऊपर के उदाहरण में एक वैरिएबल को उसी प्रकार से परिभाषित किया गया है - int। यदि आपके पास लंबे प्रकार का नाम है, या यदि आप किसी अनाम प्रकार को संदर्भित करना चाहते हैं तो यह उपयोगी है। यह अजीब है क्योंकि user1618171 ने दो परिवर्तनीय घोषणा शैलियों को मिलाया है - शायद एक टाइपो।
डैनियल जेम्स ब्रायर्स

2

मैं एक रंग को एक विशिष्ट चमक स्तर में बदलना चाहता था - कोई फर्क नहीं पड़ता कि रंग पहले क्या चमक रहा था - यहां एक सरल जेएस फ़ंक्शन है जो अच्छी तरह से काम करता है, हालांकि मुझे यकीन है कि यह छोटा हो सकता है

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

Coolio! मुझे लगता है कि pसीमा है 0-100? मैं यह भी नहीं जानता कि आरजीबी में चमक को सही ढंग से कैसे परिभाषित किया जाए, एक एचएसएल चीज। उदाहरण के लिए, क्या #FF00FFउज्जवल है #FF0000? यदि हां, तो इसका अर्थ यह होगा कि मैजेंटा लाल रंग से दोगुना चमकदार है। इसलिए, शुद्ध लाल परीक्षण का उपयोग किया जाता है। शुद्ध लाल में पास #FF0000, 50% चमक के लिए सेट, और यहाँ हम प्राप्त करते हैं #FF4040, क्या यह सही है? मुझे लगता है कि लाल 50% चमक बनाने के लिए अनुमान लगाया जाएगा, हम गहरे हो रहे हैं, यह देखकर कि इसकी पहले से ही पूरी तरह से उज्ज्वल है .. जैसा कि #800000या 150% चमक होगी #FF8080। क्या गुलाबी एक चमकदार लाल है? या लाल पहले से ही पूरी तरह से उज्ज्वल है?
पिंप ट्राइज़किट

आप सही हैं - मैंने उल्लेख किया है कि पी 1-100 की सीमा में होना चाहिए!
टॉर्बजॉर्न जोसेफ्सन

# FF00FF में लाल चैनल में मान 255, ग्रीन चैनल में 0 और ब्लू चैनल में 255 है। चैनलों में संयुक्त मूल्य जितना अधिक होगा, रंग की चमक उतनी ही अधिक होगी। संख्या पी बताती है कि हम चाहते हैं कि नया रंग 50% उज्ज्वल हो, जैसा कि मूल रंग हो सकता है। मैं 100% नहीं हूं कि # FF4040 "50% जितना संभव हो उतना सही लाल" का सही उत्तर है। गहरे रंगों का उत्पादन (इस मामले में, लाल चैनल में कम मूल्य के साथ) संशोधन की आवश्यकता होगी
Torbjörn Josefsson

हां, मैं आरजीबी में चमक के बारे में बात करने में अस्पष्टता की ओर इशारा कर रहा था। यदि एचएसएल में परिवर्तित किया जाता है, तो Lचैनल सचमुच चमक रहा है। मेरा [व्यक्तिगत मानसिक] मुद्दा यह है कि, मेरे लिए, #FF0000पूरी तरह से उज्ज्वल है। और #FF4040हल्का है, लेकिन चमकीला नहीं है .... मेरे लिए लाइटर का मतलब सफेद के करीब है, जैसे गुलाबी है। और चमक कितनी मिली, और उसका पूरा लाल हो गया, इतना लाल, पूरा चमकीला है। इसलिए, #FF0000उज्जवल नहीं बनाया जा सकता .. बल्कि हल्का .. शायद ... मैं सिर्फ एक सनकी हूँ, योग्य !! मैं वास्तव में रंग सिद्धांत नहीं जानता, सू, मैं वास्तव में सिर्फ अपनी बात कर रहा हूं ...
पिंप ट्राइजकिट

लेकिन मुझे पता है कि जब मैं अपने मॉनीटर पर ब्राइटनेस बदलता हूं, तो रेड्स मेरे लिए गुलाबी नहीं होतीं। तो शायद यही वह जगह है जहां मैंने अपना तर्क शुरू किया।
पिंप ट्राइज़किट

1

निम्नलिखित विधि आपको हेक्साडेसिमल (हेक्स) रंग स्ट्रिंग के एक्सपोज़र वैल्यू को हल्का या गहरा करने की अनुमति देगा:

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 (-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%;

0

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

यह पाब्लो के उत्तर का एक php संस्करण है। दुर्भाग्य से, अंतिम समाधान की तुलना में इसकी लंबी और धीमी है और यह रंगों को सही ढंग से हल्का नहीं करता है। यह उन्हें सटीक रूप से काला करता है। शुद्ध लाल (# FF0000) के साथ टेस्ट, 25% का हल्का (# FF4040) होना चाहिए। अंतिम समाधान v2 के केविन एम के PHP संस्करण के लिए मेरे उत्तर के अंत की जांच करें।
पिंप ट्राइज़किट

0

मैंने इसकी jQuery निर्भरता को दूर करने के लिए उत्कृष्ट xcolor लाइब्रेरी का एक पोर्ट बनाया। वहाँ एक टन के कार्य हैं जिनमें हल्के और गहरे रंग शामिल हैं।

वास्तव में, हेक्स को आरजीबी में परिवर्तित करना हल्के या गहरे रंगों से पूरी तरह से अलग कार्य है। कृपया DRY रखें। किसी भी मामले में, एक बार आपके पास आरजीबी रंग होने के बाद, आप बस अपने इच्छित प्रकाश स्तर और आरजीबी मूल्यों में से प्रत्येक के लिए आपके पास प्रकाश स्तर के बीच अंतर जोड़ सकते हैं:

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 देखें ।


मैंने अभी तक कोड का विश्लेषण नहीं किया है क्योंकि यह मेरे ओपी (गति / आकार / सटीकता) से संबंधित है। लेकिन पहली बार में कुछ टिप्पणियां की जानी हैं: 1) मैं सहमत हूं कि आरजीबी को आरजीबी में परिवर्तित करने को एक पूरी तरह से अलग कार्य के रूप में देखा जा सकता है .. यदि मेरी समस्या को एक शुष्क कार्य के साथ हल करने का इरादा था, जो एक आवश्यकता नहीं थी। यहाँ इरादा एक उत्तर (मेरा संस्करण 2 देखें) था जो सुपर फास्ट और सुपर टिनी (2 लाइनें!) था और एक जो हल्का रंग और एक हेक्स रंग को गहरा कर दिया था ... विशेष रूप से ... एक स्टैंड-अलोन आत्म-निहित के रूप में समारोह। ताकि, अपने अंतिम उपयोग में, यह एक साधारण सिंगल फंक्शन कॉल होगा। <cont>>
पिंप ट्रिकिटक

2) और लोकप्रिय मांग के अनुसार संस्करण 3 के मामले में, एक पूरी तरह से स्टैंड-अलोन स्व-निहित सार्वभौमिक कार्य करने का इरादा है, जितनी तेज़ी से और जितना संभव हो उतना छोटा, जो नेत्रहीन रूप से एक हेक्स या आरजीबी रंग ले सकता है और उनके सभी में विविधताओं। इसलिए, आरजीबी के लिए हेक्स के रूपांतरण की आवश्यकता है। <cont।>
पिंप ट्राइज़किट

3) कोड के सरल विश्लेषण पर। ऐसा लगता है कि यह बहुत धीमी गति से चलेगा और यह स्पष्ट रूप से मेरे संस्करण 2 (जो कि मेरे ओपी के लिए वास्तविक उत्तर है; संस्करण 3 जनता के लिए था) से बहुत बड़ा है। निष्पक्ष होने के लिए, मुझे अपने RGB संस्करण 2 के साथ इस कोड की तुलना करनी चाहिए जो रूपांतरण नहीं करता है और सूखापन के बारे में आपकी बात का उत्तर देता है। और सच कहूं, तो आपका पोर्ट हेक्स के लिए मेरे 2 लाइनर से ज्यादा सरल नहीं है। तो, जबकि इसका ड्रायर, इसका वास्तव में इतना नहीं है, यदि कोई हो, सरल। (शुष्कता ने समझने की क्षमता के लिए ज्यादा मदद नहीं की) <cont।>
पिंप ट्राइज़किट

4) यदि आप चाहते हैं कि मेरा RGB संस्करण 2 कोई रूपांतरण 2 पंक्ति फ़ंक्शन नहीं है। मेरे मूल ओपी के लिए मेरा विशेष समाधान हेक्स चाहता था। इसलिए दो अलग-अलग प्रकार के संस्करण हैं 2. लेकिन आप सूखापन और हेक्स रूपांतरणों के बारे में बिंदु का उल्लेख करते हैं, इसलिए हम अब वास्तव में संस्करण 3 पर ध्यान केंद्रित कर रहे हैं। संस्करण 3 बहुत बाद में आया; केवल संस्करण 2 लोकप्रिय था। <cont।>
पिंप ट्राइज़किट

5) जबकि मैं इस बात से सहमत हूँ कि सूखापन आमतौर पर सार्वभौमिकता के लिए मदद करता है। और ज्यादातर मामलों में, समझने की क्षमता के लिए। दुर्भाग्य से इस उदाहरण में एक लागत पर। ये लागतें हैं कि इसकी बहुत बड़ी और प्रतीत होने वाली बहुत धीमी है और प्रतीत होती है कि स्टैक पर (इसकी पुनरावर्ती जैसी प्रकृति के साथ) और वैश्विक (2 कार्यों; v2 की तुलना में) दोनों में अधिक मेमोरी का उपयोग किया जाता है।
पिंप ट्राइजकिट

0

मैं लंबे समय से रंगों / रंगों का उत्पादन करने में सक्षम होना चाहता हूं, यहां मेरा जावास्क्रिप्ट समाधान है:

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

कुछ उपयोग उदाहरणों से मदद मिलेगी। और शायद कुछ स्पष्टीकरण के रूप में क्यों दूसरों पर इस संस्करण। यह संस्करण काफी धीमा चलता है। और इसके बहुत लंबे समय तक। और यह सटीक रूप से छाया नहीं लगता है। ऐसा लगता है कि आपके LERP का उपयोग कर रहा है, या कुछ समान है..जो अच्छा है। दुर्भाग्य से, इसका केवल एक चैनल से, फिर उसी मूल्य का उपयोग सभी चैनलों में किया जाता है। यह सही नहीं है, उच्च सटीकता प्राप्त करने के लिए, आपको प्रत्येक चैनल को व्यक्तिगत रूप से LERP करना चाहिए। जैसा कि इस सवाल का मेरा जवाब है। प्लस इसकी छोटी और तेज और त्रुटियों के लिए जांच करता है और आरजीबी को संभालता है, और रूपांतरण करता है, मैं आगे
बढ़

एक उदाहरण उदाहरण: varyHue ("6e124c", 77) जहां पहला तर्क हेक्स में रंग का है और दूसरा प्रतिशत परिवर्तन का। एक सकारात्मक प्रतिशत परिवर्तन (अंधेरे) एक नकारात्मक मूल्य tints (lightens) परिणाम है। मैंने इस पृष्ठ पर आने से कुछ घंटे पहले अपनी दिनचर्या के रूप में अपनी पहली कोशिश लिखी थी और इसे केवल रुचि के विषय के रूप में पोस्ट किया था। मुझे नहीं पता था कि मुझे आपके प्रयास को बेहतर करना था या ऐसा करने से पहले मुझे आपकी स्वीकृति की आवश्यकता थी। यह पूरी तरह से किसी और के संदर्भ के बिना मेरा अपना काम है। मैंने LERP के बारे में नहीं सुना है, मैं इसे देखूंगा, सुझाव के लिए धन्यवाद।
user2655360

हे, ठीक है, निश्चित रूप से आपको कुछ भी करने की ज़रूरत नहीं है! और हम सब आपके प्रयासों के लिए धन्यवाद! मेरी पहली मुख्य चिंताएं पहले सूचीबद्ध थीं। आपके उत्तर में आपकी मदद करने की कोशिश कर रहा है ताकि उसे वोट मिल सकें। (हमें दिखाओ, और यह कैसे काम करता है, आदि की व्याख्या) अन्य सामान स्पष्ट रूप से सभी के ज्ञान को आगे बढ़ाने में मदद करने के लिए एक त्वरित विश्लेषण है । क्षमा करें, यदि यह थोड़ा आक्रामक लग रहा था। लेकिन एक और सुझाव यह है कि इसे #हेक्स रंगों को स्वीकार करना चाहिए । क्षमा करें यदि ऐसा लगता था .. "अनुमोदन" ... मैंने इसे सहकर्मी समीक्षा के रूप में देखा। अगर आप नहीं चाहते कि कोई आपके कोड का विश्लेषण करे, या प्रतिक्रिया दे, तो मैं क्षमा चाहता हूँ।
पिंप ट्राइज़किट

0

आपका दृष्टिकोण ठीक है :) मैं आपके लघु संस्करण को थोड़ा सरल करता हूं (संतृप्ति नियंत्रण के लिए यहां देखें )

(col,amt)=> (+('0x'+col)+amt*0x010101).toString(16).padStart(6,0)

और # और रंग श्रेणियों की जाँच के साथ संस्करण


0

मैंने एक साधारण पैकेज भी बनाया। मैंने IR ^ 3 के उत्तलता का उपयोग किया, बेशक, RGB मान IN ^ 3 में हैं जो उत्तल नहीं है इसलिए यह वास्तव में सही नहीं है

अंधेरा करने के लिए मैंने निम्नलिखित प्रयोग किया

for (let i = 0; i < rgb.length; i++) {
   rgb[i] = Math.floor(rgb[i] - ratio * rgb[i]);
}

और हल्का करने के लिए

for (let i = 0; i < rgb.length; i++) {
   rgb[i] = Math.ceil(rgb[i] + ratio * (255 - rgb[i]));
}

यहाँ पैकेज https://github.com/MarchWorks/colortone है

डेमो https://colortone.now.sh/

जिस तरह से मैं चीजों को कर रहा हूं अगर आप -1 का अनुपात पास करते हैं तो आप काले, सफेद के साथ समाप्त हो जाएंगे यदि अनुपात 1. है। 0 पासिंग के रूप में अनुपात रंग नहीं बदलेगा


0

मुझे इसकी C # में जरूरत थी, यह .net डेवलपर्स की मदद कर सकता है

public static string LightenDarkenColor(string color, int amount)
    {
        int colorHex = int.Parse(color, System.Globalization.NumberStyles.HexNumber);
        string output = (((colorHex & 0x0000FF) + amount) | ((((colorHex >> 0x8) & 0x00FF) + amount) << 0x8) | (((colorHex >> 0xF) + amount) << 0xF)).ToString("x6");
        return output;
    }

आपने "नॉन वर्किंग" फ़ंक्शन को परिवर्तित कर दिया जो अग्रणी शून्य के साथ सौदा नहीं करता है, और रकम में एफएफ से ऊपर जा सकता है, = ऊपर रंग घटक को संशोधित कर सकता है ...
बी

जब मैंने फंक्शन की कोशिश की तो यह नॉन हेक्स वैल्यूज़ (16 = 0xF) और (8 = 0x8) के कारण काम नहीं कर पाया और 8 पोज़िशन में एक रंग देता है, लेकिन अब यह बहुत अच्छा काम करता है
Nassim

क्या आपने एफएफ से बढ़ने की कोशिश की? (0xFFFFFF + 0x000004 से कहते हैं): कि अधिकतम मूल्य पर अपने कोड रोल के बजाय (0x1000003 को कहते हैं), नहीं बढ़ रही है, और विशेष रूप से स्थापित करने के 2 ऊपरी रंग घटक 00 को जो सबसे बड़ा परिवर्तन वे क्या कर सकता है ...
बी जाओ

आप सही हैं, टिप्पणी के लिए धन्यवाद, सीमा के आसपास fff और 000 के इनपुट के अलावा यह ठीक काम करेगा।
नासीम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.