color.RGBA - can some please explain this

1,154 views
Skip to first unread message

Owen Waller

unread,
Mar 20, 2016, 4:55:43 PM3/20/16
to golang-nuts
Hi Everyone,

I've got a PNG that I've decoded using png.Decode() to give me an image.Image, i.
I then call:

i.At(x,y)

to give me c, the color.Color at position x,y. So far so good.

I know the color model of the image, i, is RGBA, and a type assertion confirms this.

But, if I call c.RGBA() I'm getting back individual colour values that are > 255 i.e.greater than 8 bit per colour channel. As far as I am aware the color.RGBA type is used to represent colour using 8 bits per channel. The source would seem to confirm this:

https://golang.org/src/image/color/color.go?s=983:1021#L16

But if I look at how the RGBA method is actually implemented on the color.RGBA type, it looks like this:

https://golang.org/src/image/color/color.go?s=1023:1063#L20

which can return colour components that are larger than 255.

Can anyone explain why the bitwise ors and right shifts are required in RGBA's implementation of the RGBA() method?  I had expected to see the the method simply return the RGBA.R, RGBA.G, RGBA.B, RGBA.A fields all be it cast to uint32's.

Any explanations much appreciated.

Owen

Jan Mercl

unread,
Mar 20, 2016, 5:11:42 PM3/20/16
to go-...@kulawe.com, golang-nuts

On Sun, Mar 20, 2016 at 9:55 PM Owen Waller <go-...@kulawe.com> wrote:

> Can anyone explain why the bitwise ors and right shifts are required in RGBA's implementation of the RGBA() method? I had expected to see the the method simply return the RGBA.R, RGBA.G, RGBA.B, RGBA.A fields all be it cast to uint32's.


The color model of color.Color is, quoting, "16-bits per channel RGBA." values regardless of the particular implementation, That enables, for example, some graphic algorithms to work independently of the backing color model implementation.

The "bitwise ors and right shifts" you mention just properly scales the 8-bit per channel model to that of the, backing independent, color.Color model.
--

-j

Owen Waller

unread,
Mar 21, 2016, 11:12:42 AM3/21/16
to golang-nuts
Sorry, I forgot to reply to the list.

Owen

On Mon, 2016-03-21 at 09:27 +0000, Owen Waller wrote:
Hi Jan,

Thanks, I missed that, but....

I understand what the RGBA.RGBA() code does, I just don't see why it does this. Let me explain.

If I had a 8 bit red component with a value of 0x7f in the original image.
After a call to RGBA.RGBA() the value of the same red component is shifted to the 16 bit 0x7f7f, which seems like its a different colour.

So perhaps my question should be, why isn't the result of RGBA.RGBA() for this red component 0x007f. Which is still 16 bit, but doesn't change the colour.

Owen

--
Dr. Owen Waller
Head of Development
Kulawe Limited
Forsyth House
Cormac Square
Belfast
Northern Ireland
BT2 8LA

+44 (0)757 882 9933
in...@kulawe.com
www.kulawe.com

Company Number: NI604010
VAT Number : GB 122 6319 42


Roberto Zanotto

unread,
Mar 21, 2016, 11:21:54 AM3/21/16
to golang-nuts, o.wa...@kulawe.com
8 bit colors go from 0 to 0xff, 16 bit colors go from 0 to 0xffff, so, for example, white in 8 bit is 0xff, in 16 bit it's 0xffff. To convert from 8 to 16 bit you have to scale up.

oju...@gmail.com

unread,
Mar 21, 2016, 1:00:49 PM3/21/16
to golang-nuts, o.wa...@kulawe.com
That is the canonical way to convert a 8 bit color to a 16 bit color.
Visually speaking, 0x007f would be too dark. 0x7f00 would be not close enough to the original color.
16 bit value 0x7f7f is the closest match for 8 bit 0x7f.

Alex Bligh

unread,
Mar 21, 2016, 1:09:34 PM3/21/16
to oju...@gmail.com, Alex Bligh, golang-nuts, o.wa...@kulawe.com
Yes

r16 := (r8 << 8) | r8

etc
> --
> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

--
Alex Bligh




l...@ansync.com

unread,
Mar 21, 2016, 5:04:29 PM3/21/16
to golang-nuts, go-...@kulawe.com
Another way to look at it is that color component values are real numbers from 0.0 to 1.0. In 8 bits, then, the values represent 0/255, 1/255, ... 255/255. In 16 bits, they are 0/65535, 1/65535, ... 65535/65535. The closest value to 127/255 is not 127/65535, but 32639/65535.
Reply all
Reply to author
Forward
0 new messages