Download or view NamedColors.frink in plain text format
/** This class contains routines for working with named colors. It uses the
color names from xkcd:
See: https://blog.xkcd.com/2010/05/03/color-survey-results/
And requires the file available at:
https://xkcd.com/color/rgb.txt
which should be renamed to xkcdrgb.txt to match the value in the readFile
method.
This class contains static methods that can be used to find named colors,
to find colors with similar names, or to find colors that are similar to
a specified color.
In this file, colors are specified as [r,g,b] arrays where each value
is expected to be an integer between 0 and 255 inclusive.
*/
class NamedColors
{
/** Name to [r,g,b] dictionary */
class var nameDict = NamedColors.readFile[]
/** Takes a name and returns the [name, [r,g,b]] value for that color. If
the exact color name does not exist, this uses the closest name by
Levenshtein-Damerau edit distance.
*/
class byName[name] :=
{
name = lc[name]
color = nameDict@name
if color != undef
return [name, color]
closestDist = million
closestName = undef
closestColor = undef
for [n, color] = nameDict
{
dist = editDistanceDamerau[n, name]
if dist < closestDist
{
closestDist = dist
closestName = n
closestColor = color
}
}
return [closestName, closestColor]
}
/** Retains all the [name, [r,g,b]] values containing the specified text. */
class containingName[name] :=
{
name = lc[name]
reg = regex[name]
result = new array
for [n, color] = nameDict
{
if n =~ reg
result.push[[n, color]]
}
return sort[result, {|a,b| length[a@0] <=> length[b@0]}]
}
/** Finds the nearest named color from an array representing colors
as [r,g,b].
Returns [name, [r,g,b]]
*/
class nearestColor[array] :=
{
return nearestColor[array@0, array@1, array@2]
}
/** Finds the nearest named color. Returns [name, [r,g,b]] */
class nearestColor[r, g, b] :=
{
c1 = [r, g, b]
nearestDist = million
nearestName = undef
nearestColor = undef
for [name, c2] = nameDict
{
dist = hypotenuse[abs[subtract[c2,c1]]]
if dist < nearestDist
{
nearestDist = dist
nearestName = name
nearestColor = c2
}
}
return [nearestName, nearestColor]
}
/** Finds the nearest named colors to a color specified as an array [r,g,b].
Returns an array of [name, [r,g,b]] of length at most num. */
class nearestColors[array, num] :=
{
return nearestColors[array@0, array@1, array@2, num]
}
/** Finds the nearest named colors. Returns an array of [name, [r,g,b]]
of length at most num.
*/
class nearestColors[r, g, b, num] :=
{
c1 = [r, g, b]
result = new array
for [name, c2] = nameDict
{
dist = hypotenuse[abs[subtract[c2,c1]]]
result.push[[name, c2, dist]]
}
return first[sort[result, byColumn[2]], num]
}
/** Turns a [r,g,b] color array from 0 to 255 into a color object. */
class toColor[array] :=
{
return new color[array@0 / 255, array@1 / 255, array@2 / 255]
}
/** Turns a [r,g,b] color array from 0 to 255 into a hex string. */
class toHex[array] :=
{
return padLeft[hex[array@0], 2, "0"] +
padLeft[hex[array@1], 2, "0"] +
padLeft[hex[array@2], 2, "0"]
}
/** Parses a color from hexadecimal notation with an optional preceding
# sign. */
class fromHex[str] :=
{
if [r, g, b] = str =~ %r/#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})/
{
r = parseInt[r, 16]
g = parseInt[g, 16]
b = parseInt[b, 16]
return [r, g, b]
}
return undef
}
/** Reads and initializes from the data file. You do not need to call this;
it is called automatically on class initialization. */
class readFile[] :=
{
nd = new dict
LINE:
for line = lines["file:xkcdrgb.txt"]
{
if line =~ %r/^\s*#/
next LINE
if [name, r, g, b] = line =~ %r/(.*?)\s*#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/i
{
r = parseInt[r, 16]
g = parseInt[g, 16]
b = parseInt[b, 16]
nd@name = [r,g,b]
}
}
return nd
}
}
Download or view NamedColors.frink in plain text format
This is a program written in the programming language Frink.
For more information, view the Frink
Documentation or see More Sample Frink Programs.
Alan Eliasen, eliasen@mindspring.com