Skip to content
Prev 324433 / 398503 Next

measuring distances between colours?

Dear all,

My thanks to everyone who addressed my question. I've incorporated Eik
Vettorazzi's suggestion for improved conversion of hexadecimal RGB colours
to decimal numbers, and Martin Maechler's hint to look at demo(colors). I've
loosened the default definition of "close enough" from the latter, since the
following seems to work well for my purposes.

r2c <- function(){
    hex2dec <- function(hexnums) {
        # suggestion of Eik Vettorazzi
        sapply(strtoi(hexnums, 16L), function(x) x %/% 256^(2:0) %% 256)
    }
    findMatch <- function(dec.col) {
        sq.dist <- colSums((hsv - dec.col)^2)
        rbind(which.min(sq.dist), min(sq.dist))
    }
    colors <- colors()
    hsv <- rgb2hsv(col2rgb(colors))
    function(cols, near=0.25){
        cols <- sub("^#", "", toupper(cols))
        dec.cols <- rgb2hsv(hex2dec(cols))
        which.col <- apply(dec.cols, 2, findMatch)
        matches <- colors[which.col[1, ]]
        unmatched <- which.col[2, ] > near^2
        matches[unmatched] <- paste("#", cols[unmatched], sep="")
        matches
    }
}

rgb2col <- r2c()

For example,
"AA00AA", "00AAAA"))
[1] "black"         "gray93"        "darkred"       "green4"       
[5] "blue4"         "darkgoldenrod" "darkmagenta"   "cyan4"
"090009", "000909"))
[1] "black"   "gray3"   "#090000" "#000900" "#000009" "#090900"
[7] "#090009" "#000909"

Thanks again,
 John