Home
Manual
Packages
Global Index
Keywords
Quick Reference
|
/*
COLOR.I
Hue-Saturation-Value color representation routines and other
color and palette construction tools.
$Id$
*/
/* Copyright (c) 1996. The Regents of the University of California.
All rights reserved. */
local palette_directory ;
/* DOCUMENT palette_directory= "~/Gist/"
holds the default directory for the dump_palette command.
The directory name *must* end with "/"; the default is shown.
SEE ALSO: dump_palette
*/
palette_directory= "~/Gist/";
func dump_palette (name)
/* DOCUMENT dump_palette, name
dump the current palette under the NAME. If NAME contains no
slash characters, the palette_directory will be prepended to the
name. The name can be fed back to the palette command in order
to reload the cumped palette.
SEE ALSO: brighten, palette, palette_directory
*/
{
if (!strmatch(name,"/")) name= palette_directory+name;
local r, g, b;
palette, query=1, r, g, b;
f= create(name);
write,f, format="%s\n", "ncolors= "+pr1(numberof(r));
write,f, format="%s\n", "ntsc= 1";
write,f, format="%s\n", "# r g b";
write,f, format="%4d%4d%4d\n", r, g, b;
}
func brighten (factor)
/* DOCUMENT brighten, factor
or brighten
brighten the current palette by the specified FACTOR.
The FACTOR is the slope of the transfer function for the color value
(see to_hsv for a description of the hsv color system); a value of
1.0 always remains 1.0, but values near 0.0 change by FACTOR.
FACTOR= 1.0 is a no-op. The default factor is 4.0.
SEE ALSO: dump_palette
*/
{
if (is_void(factor)) factor= 4.0;
local r, g, b;
palette, query=1, r, g, b;
hsv= to_hsv([r,g,b]);
v= hsv(,3);
/* this function is a symmetric parabolic mapping from [0,1] to [0,1] */
fv= 0.5*(factor-1.0)*v;
n= (2.*factor-fv)*v;
d= 1.+fv+sqrt(max(1.+(factor^2-1.)*v,0.));
hsv(,3)= n/d;
/* here is an alternative which has the property that applying the
function twice is the same as applying with the product of the
two factors - however, this nice property is spoiled by the
quantization of the byte scaling of the rgb values */
/* hsv(,3)= 1.-(1.-v)^factor; */
rgb= to_rgb(hsv);
palette, rgb(,1),rgb(,2),rgb(,3);
}
func to_rgb (hsv)
/* DOCUMENT rgb= to_rgb(hsv)
or rgb= to_rgb([h,s,v])
return the RGB representation of the n-by-3 array of HSV colors
rgb: red, green, blue from 0 to 255
hsv: h= hue in degrees, red=0, green=120, blue=240
s= saturation from 0 (gray) to 1 (full hue)
v= value from 0 (black) to 1 (full intensity)
s= 1 - min(r,g,b)/max(r,g,b)
v= max(r,g,b)/255
SEE ALSO: to_hsv
*/
{
hsv= double(hsv);
h= hsv(*,1);
s= hsv(*,2);
v= hsv(*,3);
/* normalize hue to lie in 0<=h<360 */
h= h % 360.0;
h+= (h<0.0)*360.0;
/* divide hue into 60 degree sectors */
i= long(h/60.0);
f= h/60.0 - i;
p= 1.0 - s;
q= 1.0 - s*f;
t= 1.0 - s*(1.-f);
/* each hue sector will be represented by rgb values taken
* from one of v, p, q, or t */
r= ((i==0|i==5) + (i==2|i==3)*p + (i==1)*q + (i==4)*t) * v;
g= ((i==1|i==2) + (i==4|i==5)*p + (i==3)*q + (i==0)*t) * v;
b= ((i==3|i==4) + (i==0|i==1)*p + (i==5)*q + (i==2)*t) * v;
/* return array same shape as input */
rgb= hsv;
rgb(*,1)= r;
rgb(*,2)= g;
rgb(*,3)= b;
return bytscl(rgb,top=255,cmin=0.0,cmax=1.0);
}
func to_hsv (rgb)
/* DOCUMENT hsv= to_hsv(rgb)
or hsv= to_hsv([r,g,b])
return the HSV representation of the n-by-3 array of RGB colors
rgb: red, green, blue from 0 to 255
hsv: h= hue in degrees, red=0, green=120, blue=240
s= saturation from 0 (gray) to 1 (full hue)
v= value from 0 (black) to 1 (full intensity)
s= 1 - min(r,g,b)/max(r,g,b)
v= max(r,g,b)
SEE ALSO: to_rgb
*/
{
rgb/= 255.0;
hsv= rgb;
rgb= rgb(*,);
r= rgb(,1);
g= rgb(,2);
b= rgb(,3);
/* compute and normalize hue angle */
h= atan((g-b)*sqrt(0.75), r-0.5*(g+b)+1.e-30)/pi * 180.;
h+= (h<0.0)*360.;
/* any given hue is adjacent to one primary, opposite a second primary,
* and neutral for the third
* value is adjacent, which is always maximum
* the ratio of opposite to adjacent is 1-saturation */
v= max(r,g,b);
s= 1.0 - (min(r,g,b)+1.e-30)/(v+1.e-30);
hsv(*,1)= h;
hsv(*,2)= s;
hsv(*,3)= v;
return hsv;
}
|