Here's your color model function:
func rgb565Model(c color.Color) color.Color {
if _, ok := c.(Pixel565); ok {
return c
}
r, g, b, _ := c.RGBA()
r >>= (bytewid - rwid)
g >>= (bytewid - gwid)
b >>= (bytewid - bwid)
return Pixel565((r&rmask)<<roff | (g&gmask)<<goff | b&bmask)
}
The
r, g, b, _ := c.RGBA()
line gives a 16-bit red value, in the range [0x0000, 0xffff]. The
value's type is uint32, but the effective range is 16 bits. (See the
"three important subtleties" paragraph at
https://blog.golang.org/go-image-package). The next line is:
r >>= (bytewid - rwid)
or equivalently,
r >>= (8 - 5)
so that r is effectively an 13 bit value. The final line says:
r&rmask
but rmask is 0x1f, so you're masking off all but the low 5 bytes,
instead of the high 5 bytes. I suspect that it suffices to replace
r >>= (bytewid - rwid)
with
r >>= (8 + bytewid - rwid)
and the same for g and b, obviously.
Here's a quick test:
fmt.Printf("0x%04x\n", RGB565Model.Convert(color.RGBA64{
R: 0x0000,
G: 0x0000,
B: 0x8000,
A: 0xffff,
}))
should print a Pixel565 value that's 50-ish% blue: 0x0010 instead of 0x0000.