9fans.net/go@v0.0.5/draw/rgb.go (about) 1 package draw 2 3 /* 4 * This original version, although fast and a true inverse of 5 * cmap2rgb, in the sense that rgb2cmap(cmap2rgb(c)) 6 * returned the original color, does a terrible job for RGB 7 * triples that do not appear in the color map, so it has been 8 * replaced by the much slower version below, that loops 9 * over the color map looking for the nearest point in RGB 10 * space. There is no visual psychology reason for that 11 * criterion, but it's easy to implement and the results are 12 * far more pleasing. 13 * 14 int 15 rgb2cmap(int cr, int cg, int cb) 16 { 17 int r, g, b, v, cv; 18 19 if(cr < 0) 20 cr = 0; 21 else if(cr > 255) 22 cr = 255; 23 if(cg < 0) 24 cg = 0; 25 else if(cg > 255) 26 cg = 255; 27 if(cb < 0) 28 cb = 0; 29 else if(cb > 255) 30 cb = 255; 31 r = cr>>6; 32 g = cg>>6; 33 b = cb>>6; 34 cv = cr; 35 if(cg > cv) 36 cv = cg; 37 if(cb > cv) 38 cv = cb; 39 v = (cv>>4)&3; 40 return ((((r<<2)+v)<<4)+(((g<<2)+b+v-r)&15)); 41 } 42 */ 43 44 func rgb2cmap(cr, cg, cb int) int { 45 best := 0 46 bestsq := 0x7FFFFFFF 47 for i := 0; i < 256; i++ { 48 r, g, b := cmap2rgb(i) 49 sq := (r-cr)*(r-cr) + (g-cg)*(g-cg) + (b-cb)*(b-cb) 50 if sq < bestsq { 51 bestsq = sq 52 best = i 53 } 54 } 55 return best 56 } 57 58 func cmap2rgb(c int) (r, g, b int) { 59 r = c >> 6 60 v := (c >> 4) & 3 61 j := (c - v + r) & 15 62 g = j >> 2 63 b = j & 3 64 den := r 65 if g > den { 66 den = g 67 } 68 if b > den { 69 den = b 70 } 71 if den == 0 { 72 v *= 17 73 return v, v, v 74 } 75 num := 17 * (4*den + v) 76 r = r * num / den 77 g = g * num / den 78 b = b * num / den 79 return 80 } 81 82 func cmap2rgba(c int) Color { 83 r, g, b := cmap2rgb(c) 84 return Color(r<<24 | g<<16 | b<<8 | 0xFF) 85 }