프로그램적으로 16진수 색상(또는 rgb 및 혼합 색상)을 밝게 또는 어둡게 합니다.
여기 16진수 색상을 특정량만큼 프로그램적으로 밝게 하거나 어둡게 하는 기능이 있습니다. '나'와 같은 해 주세요."3F6D2A"
색채))col
정수base 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);
제 주된 질문은, 제가 여기 있는 게 맞나요?여기에는 일부(정상) 상황이 포함되지 않습니까?
음, 이 대답은 그 자체의 야수가 되었다.많은 새로운 버전들이, 멍청하게 길어지고 있었다.이 답변에 많은 기여자들에게 감사드립니다.하지만 대중을 위해 단순함을 유지하기 위해.나는 이 답변의 모든 버전/이력을 내 github에 보관했다.그리고 여기 StackOverflow에서 최신 버전으로 새로 시작했어요.이 버전에 대해 Mike 'Pomax' Kamermans에게 특별한 감사를 전합니다.그는 나에게 새로운 수학을 주었다.
함수 능능( this this this thispSBC
는, 의 컬러가 、 HEX 、 RGB 、 Web ( Web ) 。 pSBC
는, 어둡게 하거나 밝게 하거나, 세컨드 컬러로 블렌딩 하거나 할 수 있습니다.【16진】RGB(Hex2RGB) RGB(RGB2Hex) RGB(RGB2Hex) RGB(RGB2Hex)】RGB(Hex) RGB(RGB2Hex) RGB(RGB2Hex) RGB.어떤 컬러 포맷을 사용하고 있는지조차 알 수 없습니다.
특히 많은 기능을 고려할 때, 이것은 매우 빠르게, 아마도 가장 빠르게 실행될 것입니다.만드는 데 오랜 시간이 걸렸다.내 기써브에서 모든 이야기를 봐.음영 또는 혼합을 가능한 한 가장 작고 빠르게 하고 싶다면 아래의 마이크로 기능을 참조하여 2-라이너 속도 악령 중 하나를 사용하십시오.강렬한 애니메이션에 매우 적합하지만, 이 버전은 대부분의 애니메이션에 충분히 빠릅니다.
이 함수는 로그 혼합 또는 선형 혼합을 사용합니다.그러나 색을 적절하게 밝게 하거나 어둡게 하기 위해 HSL로 변환되지 않습니다.따라서 이 함수의 결과는 HSL을 사용하는 훨씬 크고 느린 함수와 다릅니다.
특징:
- 표준 16진수 색상을 문자열 형태로 자동 검출하여 받아들입니다.를 들면, '먹다'와 같이요.
"#AA6622"
★★★★★★★★★★★★★★★★★」"#bb551144"
. - 표준 RGB 색상을 문자열 형태로 자동 검출하여 받아들입니다.를 들면, '먹다'와 같이요.
"rgb(123,45,76)"
★★★★★★★★★★★★★★★★★」"rgba(45,15,74,0.45)"
. - 흰색 또는 검정색으로 비율별로 음영 처리.
- 백분율로 색상을 혼합합니다.
- Hex2RGB와 RGB2Hex를 동시에 변환하거나 단독으로 변환합니다.
- #RGB(또는 #RGBA) 형식으로 3자리(또는 4자리(알파 포함) HEX 색상 코드를 사용할 수 있습니다.그것은 그들을 확장시킬 것이다. ::
"#C41"
becomes가 되다"#CC4411"
. - 수용 및 (선형) 혼합 알파 채널을 사용합니다.는,
c0
from) (from) 색상c1
채널을 , 을 가지고 있습니다.두 색상에 모두 알파 채널이 있는 경우 반환되는 색상은 주어진 백분율을 사용하여 두 알파 채널의 선형 혼합이 됩니다(일반 색상 채널인 것처럼).두 가지 색상 중 하나만 알파 채널을 가질 경우 이 알파는 반환된 색상으로 전달됩니다.투명도를 유지하면서 투명 색상을 블렌딩/쉐이딩할 수 있습니다.또는 투명도도 혼합이 필요한 경우 두 색 모두 알파벳을 사용합니다.음영 처리 시 알파 채널을 직선으로 통과시킵니다.인 음영을 는, 「알파 채널」을 합니다.rgb(0,0,0,1)
★★★★★★★★★★★★★★★★★」rgb(255,255,255,1)
c1
color (그 16진수 등가 (to) 경우 색상의 됩니다.RGB 색상의 경우 반환되는 색상의 알파 채널은 소수점 이하 3자리 반올림됩니다. - RGB2Hex, Hex2RGB, Hex2RGB, Hex2RGB입니다.★★★★★★★★★에 관계없이
c0
color. (from)의 컬러 입니다. 반환되는 색상은 항상 의 색상 형식입니다.c1
color하는 경우). (to) color(to)가 없는c1
칠하고 그 에 통과하다'c'
c1
을 하면 어떤 을 주고 할 수 .c0
통과합니다.0
비율))로)p
도 마찬가지입니다을 사용하다 경우,c1
이 빠지지 않습니다.string
이치노 - 이치노
pSBCr
는 16진수 또는 RGB 색상을 전달할 수 있으며 이 색상 정보를 포함하는 개체를 반환합니다.식 : {r : XXX 、 g : XXX 、 b : XXX 、 a : X 。XX. 여기서 ★★★★★★★★★★★★★..r
,.g
, , , , 입니다..b
0에서 255까지입니다.: 알가가는 and and and and and and:.a
그렇지 않으면 -1이 됩니다.다음 중 하나:.a
0.000~1.000이다. - 출력의 RGB 출의 rgb for rgb for for for for for rgb for rgb rgb rgb rgb rgb rgb 。
rgba()
에 걸쳐서rgb()
을 가진 이 ''로 때c0
(from) / (from)c1
로 - 이치노그건 완벽하지 않다.크래시하거나 지브리쉬를 생성할 수 있습니다.하지만 뭔가 잡힐 거예요.경우 됩니다.
null
. : :pSBC(0.5,"salt") == null
#salt
유효한 색상입니다. 4행으로 .return null;
이 기능을 제거하고 더 빠르고 더 작게 만들 수 있습니다. - 로그 혼합을 사용합니다.
true
있습니다.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=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}
아래 그림은 두 가지 혼합 방법의 차이를 보여주는 데 도움이 됩니다.
마이크로 함수
속도와 크기를 원한다면 HEX가 아닌 RGB를 사용해야 합니다.RGB는 보다 간단하고 심플하며, HEX는 쓰기 속도가 너무 느리고, 단순한 2라인에서는 너무 많은 맛이 나옵니다(즉, 3, 4, 6, 또는8 자리수의 HEX 코드일 수 있습니다).또, 에러 체크나 HEX2RGB 또는 RGB2를 실시하지 않는 등, 일부의 기능을 희생할 필요가 있습니다.HEX. 또한 컬러 블렌딩 산술과 음영 또는 블렌딩 산술에 대해 특정 함수(아래 함수 이름 기준)를 선택해야 합니다.이러한 기능은 알파 채널을 지원합니다.그리고 두 입력 색상에 알파벳이 있으면 선형 혼합됩니다.만약 두 가지 색상 중 하나만 알파를 가지고 있다면, 그것은 결과 색상으로 곧장 전달될 것입니다.다음은 매우 빠르고 작은 두 가지 라이너 기능입니다.
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:")");
}
자세한 정보 필요하세요?github의 모든 글을 읽어보세요.
PT
(P.s. 다른 블렌딩 방법에 대한 계산을 할 수 있는 사람이 있다면 공유해 주세요.
나는 나에게 매우 도움이 되는 솔루션을 만들었다.
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);
에릭의 답변을 바탕으로 한 초심플한 라이너입니다.
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센트를 추가하겠습니다.다른 답변의 만족스러운 조합입니다.
const colorShade = (col, amt) => {
col = col.replace(/^#/, '')
if (col.length === 3) col = col[0] + col[0] + col[1] + col[1] + col[2] + col[2]
let [r, g, b] = col.match(/.{2}/g);
([r, g, b] = [parseInt(r, 16) + amt, parseInt(g, 16) + amt, parseInt(b, 16) + amt])
r = Math.max(Math.min(255, r), 0).toString(16)
g = Math.max(Math.min(255, g), 0).toString(16)
b = Math.max(Math.min(255, b), 0).toString(16)
const rr = (r.length < 2 ? '0' : '') + r
const gg = (g.length < 2 ? '0' : '') + g
const bb = (b.length < 2 ? '0' : '') + b
return `#${rr}${gg}${bb}`
}
accepts로 #
6면 3면 3면이다.
: " " 。colorShade('#54b946', -40)
3가지 색조가 밝은 색상과 어두운 색상의 4가지 색상의 출력을 나타냅니다(여기서는 40의 배수).
이것은 당신의 기능에 근거해 사용한 것입니다.보다 직관적이기 때문에 백분율보다 스텝을 더 많이 사용하는 것이 좋습니다.
예를 들어, 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;
}
당신의 함수를 시험해 봤는데, 약간의 버그가 있었습니다.예를 들어 최종 '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;
그렇게 좋진 않지만 효과가 있어요.좋은 기능이야, BTW 내가 필요했던 거야:)
위의 답변에 근거해, David Sherret와 Pablo는 Typescript를 위한 안전한 버전으로 솔루션을 변환했습니다.
/**
* @param color Hex value format: #ffffff or ffffff
* @param decimal lighten or darken decimal value, example 0.5 to lighten by 50% or 1.5 to darken by 50%.
*/
static shadeColor(color: string, decimal: number): string {
const base = color.startsWith('#') ? 1 : 0;
let r = parseInt(color.substring(base, 3), 16);
let g = parseInt(color.substring(base + 2, 5), 16);
let b = parseInt(color.substring(base + 4, 7), 16);
r = Math.round(r / decimal);
g = Math.round(g / decimal);
b = Math.round(b / decimal);
r = (r < 255)? r : 255;
g = (g < 255)? g : 255;
b = (b < 255)? b : 255;
const rr = ((r.toString(16).length === 1)? `0${r.toString(16)}` : r.toString(16));
const gg = ((g.toString(16).length === 1)? `0${g.toString(16)}` : g.toString(16));
const bb = ((b.toString(16).length === 1)? `0${b.toString(16)}` : b.toString(16));
return `#${rr}${gg}${bb}`;
}
rgb > hsl 변환에 대해 생각해 본 적이 있습니까?광도를 위아래로 움직이면 되나요?저라면 그렇게 갈 거예요
몇 가지 알고리즘을 찾아봤더니 다음 사이트를 찾았어요.
PHP: http://serennu.com/colour/rgbtohsl.php
위의 EDIT 링크는 더 이상 유효하지 않습니다.페이지 소스 또는 GIST에 대한 git 허브를 볼 수 있습니다.
또는 다른 StackOverflow 질문을 참조하는 것이 좋습니다.
이것이 OP에 대한 올바른 선택은 아니지만, 아래는 제가 처음에 제안했던 코드의 근사치입니다.(rbg/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;
}
여기에는 다음이 포함됩니다.
- 요.
hslToRgb
★★★★★★★★★★★★★★★★★」rgbToHsl
. - '''
colorValue
는 #RGBB 형식의 문자열입니다.
css에 대해 논의하는 경우 IE9/Chrome/Firefox에 대해 hsl/hsla를 지정하는 구문이 있습니다.
접근법은 OK입니다:) 최단 버전을 조금 간략화합니다(채도 조절을 위해 여기를 참조).
(col,amt)=> (+('0x'+col)+amt*0x010101).toString(16).padStart(6,0)
// Similar to OP shortest version, we not have here # and colors range checking
var LightenDarkenColor =
(col,amt) => (+('0x'+col)+amt*0x010101).toString(16).padStart(6,0);
// ------
// TEST
// ------
function update() {
let c= col.value.padEnd(6,'0').slice(0,6);
let color = '#'+LightenDarkenColor(c, +amt.value);
oldColor.innerHTML = 'Old: #'+c;
oldColor.style = `background: #${c}`;
newColor.innerHTML = 'New: '+color
newColor.style = `background: ${color}`;
}
update();
.box{ width: 100px; height: 100px; margin: 10px; display: inline-block}
<input id="col" value="3F6D2A" oninput="update()">
<input id="amt" value="30" oninput="update()"><br>
<div id="oldColor" class="box"></div>
<div id="newColor" class="box"></div>
그리고 #와 색상 범위를 체크하는 버전
// # and colors range checking
var LightenDarkenColor =
(col,amt) => '#'+col.slice(1).match(/../g)
.map(x=>(x=+`0x${x}`+amt,x<0?0:(x>255?255:x))
.toString(16).padStart(2,0)).join``;
// ------
// TEST
// ------
function update() {
let c= col.value.padEnd(6,'0').slice(0,7);
let color = LightenDarkenColor(c, +amt.value);
oldColor.innerHTML = 'Old: '+c;
oldColor.style = `background: ${c}`;
newColor.innerHTML = 'New: '+color
newColor.style = `background: ${color}`;
}
update();
.box{ width: 100px; height: 100px; margin: 10px; display: inline-block}
<input id="col" value="#3F6D2A" oninput="update()">
<input id="amt" value="40" oninput="update()"><br>
<div id="oldColor" class="box"></div>
<div id="newColor" class="box"></div>
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);
}
이전 밝기와 상관없이 특정 밝기 수준으로 색상을 변경하고 싶었습니다. 더 짧을 수 있지만 잘 작동하는 것처럼 보이는 간단한 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;}
나는 단지 '#' 뒤에 오는 16진수를 사용했다.
var x = 0xf0f0f0;
x=x+0xf00; //set this value as you wish programatically
document.getElementById("heading").style = 'background-color: #'+x.toString(16);
수를 늘리다
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;
}
타이프 스크립트로 작성된 내 버전:
function changeColorLightness(color: number, lightness: number): number {
return (Math.max(0, Math.min(((color & 0xFF0000) / 0x10000) + lightness, 0xFF)) * 0x10000) +
(Math.max(0, Math.min(((color & 0x00FF00) / 0x100) + lightness, 0xFF)) * 0x100) +
(Math.max(0, Math.min(((color & 0x0000FF)) + lightness, 0xFF)));
}
설명:
export function changeColorLightness(color: number, lightness: number): number {
const r = (color & 0xFF0000) / 0x10**4;
const g = (color & 0x00FF00) / 0x10**2;
const b = (color & 0x0000FF);
const changedR = Math.max(0, Math.min(r + lightness, 0xFF));
const changedG = Math.max(0, Math.min(g + lightness, 0xFF));
const changedB = Math.max(0, Math.min(b + lightness, 0xFF));
return (changedR * 0x10**4) + (changedG * 0x10**2) + changedB;
}
사용방법:
changeColorLightness(0x00FF00, 0x50);
changeColorLightness(parseInt("#00FF00".replace('#',''), 16), 0x50);
changeColorLightness(0x00FF00, 127.5);
다음 방법을 사용하면 16진수(16진수) 색상 문자열의 노출 값을 밝거나 어둡게 할 수 있습니다.
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%;
00 ie "#000623"부터 시작하는 색상은 지원되지 않습니다만, 여기 수정 사항이 있습니다.
function lightenDarkenColor(colorCode, amount) {
let usePound = false;
if (colorCode[0] == "#") {
colorCode = colorCode.slice(1);
usePound = true;
}
const num = parseInt(colorCode, 16);
let r = (num >> 16) + amount;
if (r > 255) {
r = 255;
} else if (r < 0) {
r = 0;
}
let b = ((num >> 8) & 0x00FF) + amount;
if (b > 255) {
b = 255;
} else if (b < 0) {
b = 0;
}
let g = (num & 0x0000FF) + amount;
if (g > 255) {
g = 255;
} else if (g < 0) {
g = 0;
}
let color = (g | (b << 8) | (r << 16)).toString(16);
while (color.length < 6){
color = 0 + color;
}
return (usePound ? '#' : '') + color;
}
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
jQuery 의존성을 없애기 위해 우수한 xcolor 라이브러리의 포트를 만들었습니다.라이트닝, 다크닝 등 다양한 기능이 탑재되어 있습니다.
실제로 16진수를 RGB로 변환하는 것은 밝은 색이나 어두운 색과는 전혀 다른 기능입니다.건조하게 보관해 주세요.어떤 경우에도 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 를 참조해 주세요.
저는 오랫동안 색조나 음영을 만들 수 있기를 원했습니다. 다음은 저의 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);
}
};
언급URL : https://stackoverflow.com/questions/5560248/programmatically-lighten-or-darken-a-hex-color-or-rgb-and-blend-colors
'programing' 카테고리의 다른 글
JavaScript에서는 ? : (조건부) 연산자를 어떻게 사용합니까? (0) | 2022.09.26 |
---|---|
MySQL을 사용하여 타임스탬프 가져오기 (0) | 2022.09.26 |
공장 패턴과 전략 패턴의 차이점은 무엇입니까? (0) | 2022.09.26 |
'for' 루프 내부의 'for' 루프가 동일한 카운터 변수 이름을 사용할 수 있습니까? (0) | 2022.09.26 |
PHP의 opcode를 얻는 방법 (0) | 2022.09.26 |