Anda dapat membuat halaman dokumentasi untuk buat pada modul Scribunto ini.
Penyunting dapat melakukan uji coba pada halaman bak pasir (buat | cermin) dan kasus uji (buat) modul ini.
Subhalaman modul ini.
Penyunting dapat melakukan uji coba pada halaman bak pasir (buat | cermin) dan kasus uji (buat) modul ini.
Subhalaman modul ini.
-- Introduction: https://colorspace.r-forge.r-project.org/articles/color_spaces.html localp={} localfunctionisempty(v) returnv==nilorv=='' end localfunctionhexToRgb(color) localcleanColor=color:gsub("#","#"):match('^[%s#]*(.-)[%s;]*$') if(#cleanColor==6)then return{ r=tonumber(string.sub(cleanColor,1,2),16), g=tonumber(string.sub(cleanColor,3,4),16), b=tonumber(string.sub(cleanColor,5,6),16) } elseif(#cleanColor==3)then return{ r=17*tonumber(string.sub(cleanColor,1,1),16), g=17*tonumber(string.sub(cleanColor,2,2),16), b=17*tonumber(string.sub(cleanColor,3,3),16) } end error("Invalid hexadecimal color "..cleanColor,1) end p._hexToRgb=hexToRgb localfunctionround(v) if(v<0)then returnmath.ceil(v-0.5) else returnmath.floor(v+0.5) end end localfunctionrgbToHex(r,g,b) returnstring.format("%02X%02X%02X",round(r),round(g),round(b)) end p._rgbToHex=rgbToHex localfunctionrgbToCmyk(r,g,b) if(r>255org>255orb>255orr<0org<0orb<0)then error("Color level out of bounds") end localc=1-r/255 localm=1-g/255 localy=1-b/255 localk=math.min(c,m,y) if(k==1)then c=0 m=0 y=0 else locald=1-k c=(c-k)/d m=(m-k)/d y=(y-k)/d end return{c=c*100,m=m*100,y=y*100,k=k*100} end p._rgbToCmyk=rgbToCmyk localfunctionrgbToHsl(r,g,b) if(r>255org>255orb>255orr<0org<0orb<0)then error("Color level out of bounds") end localchannelMax=math.max(r,g,b) localchannelMin=math.min(r,g,b) localrange=channelMax-channelMin localh,s if(range==0)then h=0 elseif(channelMax==r)then h=60*((g-b)/range) if(h<0)then h=360+h end elseif(channelMax==g)then h=60*(2+(b-r)/range) else h=60*(4+(r-g)/range) end localL=channelMax+channelMin if(L==0orL==510)then s=0 else s=100*range/math.min(L,510-L) end return{h=h,s=s,l=L*50/255} end p._rgbToHsl=rgbToHsl localfunctionrgbToHsv(r,g,b) if(r>255org>255orb>255orr<0org<0orb<0)then error("Color level out of bounds") end localchannelMax=math.max(r,g,b) localchannelMin=math.min(r,g,b) localrange=channelMax-channelMin localh,s if(range==0)then h=0 elseif(channelMax==r)then h=60*((g-b)/range) if(h<0)then h=360+h end elseif(channelMax==g)then h=60*(2+(b-r)/range) else h=60*(4+(r-g)/range) end if(channelMax==0)then s=0 else s=100*range/channelMax end return{h=h,s=s,v=channelMax*100/255} end p._rgbToHsv=rgbToHsv -- c in [0, 255], condition tweaked for no discontinuity -- http://entropymine.com/imageworsener/srgbformula/ localfunctiontoLinear(c) if(c>10.314300250662591)then returnmath.pow((c+14.025)/269.025,2.4) else returnc/3294.6 end end localfunctiontoNonLinear(c) if(c>0.00313066844250063)then return269.025*math.pow(c,1.0/2.4)-14.025 else return3294.6*c end end localfunctionsrgbToCielchuvD65o2deg(r,g,b) if(r>255org>255orb>255orr<0org<0orb<0)then error("Color level out of bounds") end localR=toLinear(r) localG=toLinear(g) localB=toLinear(b) -- https://github.com/w3c/csswg-drafts/issues/5922 localX=0.1804807884018343*B+0.357584339383878*G+0.41239079926595934*R localY=0.07219231536073371*B+0.21263900587151027*R+0.715168678767756*G localZ=0.01933081871559182*R+0.11919477979462598*G+0.9505321522496607*B localL,C,h if(Y>0.00885645167903563082)then L=116*math.pow(Y,1/3)-16 else L=Y*903.2962962962962962963 end if((r==gandg==b)orL==0)then C=0 h=0 else d=X+3*Z+15*Y if(d==0)then C=0 h=0 else -- 0.19783... and 0.4631... computed with extra precision from (X,Y,Z) when (R,G,B) = (1,1,1), -- in which case (u,v) ≈ (0,0) localus=4*X/d-0.19783000664283678994 localvs=9*Y/d-0.46831999493879099801 h=math.atan2(vs,us)*57.2957795130823208768 if(h<0)then h=h+360 elseif(h==0)then h=0-- ensure zero is positive end C=math.sqrt(us*us+vs*vs)*13*L if(C==0)then C=0 h=0 end end end return{L=L,C=C,h=h} end p._srgbToCielchuvD65o2deg=srgbToCielchuvD65o2deg localfunctionsrgbMix(t,r0,g0,b0,r1,g1,b1) if(t>1ort<0)then error("Interpolation parameter out of bounds") end if(r0>255org0>255orb0>255orr1>255org1>255orb1>255orr0<0org0<0orb0<0orr1<0org1<0orb1<0)then error("Color level out of bounds") end localtc=1-t return{ r=toNonLinear(tc*toLinear(r0)+t*toLinear(r1)), g=toNonLinear(tc*toLinear(g0)+t*toLinear(g1)), b=toNonLinear(tc*toLinear(b0)+t*toLinear(b1)) } end localfunctionformatToPrecision(value,p) returnstring.format("%."..p.."f",value) end localfunctiongetFractionalZeros(p) if(p>0)then return"."..string.rep("0",p) else return"" end end functionp.hexToRgbTriplet(frame) localargs=frame.argsorframe:getParent().args localhex=args[1] if(hex)then localrgb=hexToRgb(hex) returnrgb.r..', '..rgb.g..', '..rgb.b else return"" end end functionp.rgbTripletToHex(frame) localargs=frame.argsorframe:getParent().args localr=tonumber(args[1]) localg=tonumber(args[2]) localb=tonumber(args[3]) if(isempty(r)orisempty(g)orisempty(b))then return"" else returnrgbToHex(r,g,b) end end functionp.hexToCmyk(frame) localargs=frame.argsorframe:getParent().args localhex=args[1] if(hex)then localp=tonumber(args.precision)or0 locals=args.pctsignor"1" localrgb=hexToRgb(hex) localcmyk=rgbToCmyk(rgb.r,rgb.g,rgb.b) localfk=formatToPrecision(cmyk.k,p) localfc,fm,fy localfracZeros=getFractionalZeros(p) if(fk==100..fracZeros)then localfZero=0..fracZeros fc=fZero fm=fZero fy=fZero else fc=formatToPrecision(cmyk.c,p) fm=formatToPrecision(cmyk.m,p) fy=formatToPrecision(cmyk.y,p) end if(s~="0")then returnfc.."%, "..fm.."%, "..fy.."%, "..fk.."%" else returnfc..", "..fm..", "..fy..", "..fk end else return"" end end functionp.hexToHsl(frame) localargs=frame.argsorframe:getParent().args localhex=args[1] if(hex)then localp=tonumber(args.precision)or0 localrgb=hexToRgb(hex) localhsl=rgbToHsl(rgb.r,rgb.g,rgb.b) localfl=formatToPrecision(hsl.l,p) localfs,fh localfracZeros=getFractionalZeros(p) localfZero=0..fracZeros if(fl==fZeroorfl==100..fracZeros)then fs=fZero fh=fZero else fs=formatToPrecision(hsl.s,p) if(fs==fZero)then fh=fZero else fh=formatToPrecision(hsl.h,p) if(fh==360..fracZeros)then fh=fZero-- handle rounding to 360 end end end returnfh.."°, "..fs.."%, "..fl.."%" else return"" end end functionp.hexToHsv(frame) localargs=frame.argsorframe:getParent().args localhex=args[1] if(hex)then localp=tonumber(args.precision)or0 localrgb=hexToRgb(hex) localhsv=rgbToHsv(rgb.r,rgb.g,rgb.b) localfv=formatToPrecision(hsv.v,p) localfs,fh localfracZeros=getFractionalZeros(p) localfZero=0..fracZeros if(fv==fZero)then fh=fZero fs=fZero else fs=formatToPrecision(hsv.s,p) if(fs==fZero)then fh=fZero else fh=formatToPrecision(hsv.h,p) if(fh==360..fracZeros)then fh=fZero-- handle rounding to 360 end end end returnfh.."°, "..fs.."%, "..fv.."%" else return"" end end functionp.hexToCielch(frame) localargs=frame.argsorframe:getParent().args localhex=args[1] if(hex)then localp=tonumber(args.precision)or0 localrgb=hexToRgb(hex) localLCh=srgbToCielchuvD65o2deg(rgb.r,rgb.g,rgb.b) localfL=formatToPrecision(LCh.L,p) localfC,fh localfracZeros=getFractionalZeros(p) localfZero=0..fracZeros if(fL==fZeroorfL==100..fracZeros)then fC=fZero fh=fZero else fC=formatToPrecision(LCh.C,p) if(fC==fZero)then fh=fZero else fh=formatToPrecision(LCh.h,p) if(fh==360..fracZeros)then fh=fZero-- handle rounding to 360 end end end returnfL..", "..fC..", "..fh.."°" else return"" end end functionp.hexMix(frame) localargs=frame.argsorframe:getParent().args localhex0=args[1] localhex1=args[2] if(isempty(hex0)orisempty(hex1))then return"" end localt=tonumber(args[3]) ifnottthen t=0.5 else localmin=tonumber(args.min)or0 localmax=tonumber(args.max)or100 if(min>=max)then error("Minimum proportion greater than or equal to maximum") elseif(t<min)then t=0 elseif(t>max)then t=1 else t=(t-min)/(max-min) end end localrgb0=hexToRgb(hex0) localrgb1=hexToRgb(hex1) localrgb=srgbMix(t,rgb0.r,rgb0.g,rgb0.b,rgb1.r,rgb1.g,rgb1.b) returnrgbToHex(rgb.r,rgb.g,rgb.b) end returnp