package color import ( "image/color" ) // ToNRGBA converts a color to RGBA values which are not premultiplied, unlike color.RGBA(). func ToNRGBA(c color.Color) (r, g, b, a int) { // We use UnmultiplyAlpha with RGBA, RGBA64, and unrecognized implementations of Color. // It works for all Colors whose RGBA() method is implemented according to spec, but is only necessary for those. // Only RGBA and RGBA64 have components which are already premultiplied. switch col := c.(type) { // NRGBA and NRGBA64 are not premultiplied case color.NRGBA: r = int(col.R) g = int(col.G) b = int(col.B) a = int(col.A) case *color.NRGBA: r = int(col.R) g = int(col.G) b = int(col.B) a = int(col.A) case color.NRGBA64: r = int(col.R) >> 8 g = int(col.G) >> 8 b = int(col.B) >> 8 a = int(col.A) >> 8 case *color.NRGBA64: r = int(col.R) >> 8 g = int(col.G) >> 8 b = int(col.B) >> 8 a = int(col.A) >> 8 // Gray and Gray16 have no alpha component case *color.Gray: r = int(col.Y) g = int(col.Y) b = int(col.Y) a = 0xff case color.Gray: r = int(col.Y) g = int(col.Y) b = int(col.Y) a = 0xff case *color.Gray16: r = int(col.Y) >> 8 g = int(col.Y) >> 8 b = int(col.Y) >> 8 a = 0xff case color.Gray16: r = int(col.Y) >> 8 g = int(col.Y) >> 8 b = int(col.Y) >> 8 a = 0xff // Alpha and Alpha16 contain only an alpha component. case color.Alpha: r = 0xff g = 0xff b = 0xff a = int(col.A) case *color.Alpha: r = 0xff g = 0xff b = 0xff a = int(col.A) case color.Alpha16: r = 0xff g = 0xff b = 0xff a = int(col.A) >> 8 case *color.Alpha16: r = 0xff g = 0xff b = 0xff a = int(col.A) >> 8 default: // RGBA, RGBA64, and unknown implementations of Color r, g, b, a = unmultiplyAlpha(c) } return } // unmultiplyAlpha returns a color's RGBA components as 8-bit integers by calling c.RGBA() and then removing the alpha premultiplication. // It is only used by ToRGBA. func unmultiplyAlpha(c color.Color) (r, g, b, a int) { red, green, blue, alpha := c.RGBA() if alpha != 0 && alpha != 0xffff { red = (red * 0xffff) / alpha green = (green * 0xffff) / alpha blue = (blue * 0xffff) / alpha } // Convert from range 0-65535 to range 0-255 r = int(red >> 8) g = int(green >> 8) b = int(blue >> 8) a = int(alpha >> 8) return }