以下のコードは、ユークリッド距離アルゴリズムの作業に由来します。カラー テーブルは、アルゴリズムをテストするための手段に過ぎませんでした。車輪の再発明かもしれませんが、それ自体は役に立ちます。任意の 3 つの RGB 整数 (0 ~ 255) を、最も近い X11 カラー名に関連付けることができます。svickの洞察に感謝します。
現在のコードでは、インスタンスの作成後に AddColor メソッドによって ColorTable が初期化されます。ただし、loadrgb/colorinfo の組み合わせを使用して、Web から X11 カラー テーブルを取得できます。
X11 rgb.txt ファイルのオンライン バージョンからカラー テーブルを初期化する際に、最後の問題が 1 つあります。テキストを {Name: Values:} リストに解析する必要があります。現在、結果は文字列のタプルになっています。「colorinfo」に「ColorTable」をロードさせる作業を行っています。
// currently the color table is create via the AddColor method, however
// the initial values should be created with the loadrgb and colorinfo members
type MyFSColorTable() =
// pull the X11 rgb.txt color table off the web in text format
static let loadrgb =
let url = "http://people.csail.mit.edu/jaffer/Color/rgb.txt"
let req = WebRequest.Create(url)
let resp = req.GetResponse()
let stream = resp.GetResponseStream()
let reader = new StreamReader(stream)
let txt = reader.ReadToEnd()
txt
// parse the text of the rgb.txt color table into a Name: Values: list
static let colorinfo =
loadrgb.Split([|'\n'|])
|> Seq.skip 1
|> Seq.map (fun line -> line.Split([|'\t'|]))
|> Seq.filter (fun values -> values |> Seq.length = 3)
|> Seq.map (fun values -> string values.[0], string values.[2])
|> Seq.map (fun (rgb, name) -> rgb.Split([|' '|]), name)
|> Seq.map (fun (rgb, name) -> [|name, rgb.[0], rgb.[1], rgb.[2]|])
// Mutable Color Table will be defined on-the-fly
let mutable ColorTable = []
// Euclidean distance between 2 vectors - float is overkill here
static let Dist (V1: float[]) V2 =
Array.zip V1 V2
|> Array.map (fun (v1, v2) -> pown (v1 - v2) 2)
|> Array.sum
// Add new colors to the head of the ColorTable
member x.AddColor name rgb = ColorTable <- {Name = name; Values = rgb}::ColorTable
// Find nearest color by calculating euclidean distance of all colors,
// then calling List.minBy for the smallest
member x.FindNearestColor (rgb : float[]) =
let nearestColor =
ColorTable |> List.minBy (fun color -> Dist rgb color.Values)
nearestColor.Name