@thomthom said:
@dan rathbun said:
> > c1 = Sketchup;;Color.new( 255 )
> > Color(255, 0, 0, 255)
> > # You'd expect (0,0,255,255) ...but
> >
Ah! They treat a single int as a full colour code. Used to do this stuff in VB apps that used long
ints for colours.
YES.. a single arg is 'read' as either a ColorNameString or a 32bitColorInteger (not read as a 8bitColorComponentByte, unless 3 or 4 args are given.)
@thomthom said:
Why are you expecting a blue value from that? Getting a Red colour is what I'd expect, going left to right in RGB...
Because I was thinking of the 'newer' way of representing colors in binary (in which the blue is the lowest order byte); and you are refering to the 'older' way (in which the red is the lowest order byte.)
So both of us are both wrong and correct at the same time.
@thomthom said:
You get the int by first extracting the rgb components, then:...
Actually I was using bit shifting, it's easier for me to understand, makes for a compact looking method, and is supposed to be much faster on 32 bit architecture.
The truth (after several hours of research,) is that the whole story is more complex. The binary [integer] format AND the array [component] format for colors depends on platform, specification (ie things changed over time,) and what graphics library is in use by the color.
The 'old' way you remember is the RGB format, which was a 24bit integer, and had the red as the low-order byte; the blue as the high (3rd) byte. The math you describe will work for this... see previous post, refering to VB coding days.
Then came Win32. Colors were expressed as 32bit integers, but the industry could not agree on what the extra 4th byte was to be used for. Win32 was released with the 'old' GDI library using the COLOREF structure; it was the same as the 24bit RGB but the 4th byte was labeled 'Reserved' and had to be set to 00 if specified. (I think it defaulted to 00 as well.)
Later, came, the GDI+ library and .NET; and by that time the alpha camp won out, and the 4th byte became the 'aplha channel.' BUT... they changed the format to ARGB format:
[C from WinowsSDK::GdiPlusColor.h:beginline 288]
// Shift count and bit mask for A, R, G, B components
enum
{
AlphaShift = 24,
RedShift = 16,
GreenShift = 8,
BlueShift = 0
};
enum
{
AlphaMask = 0xff000000,
RedMask = 0x00ff0000,
GreenMask = 0x0000ff00,
BlueMask = 0x000000ff
};
// Assemble A, R, G, B values into a 32-bit integer
static ARGB MakeARGB(IN BYTE a,
IN BYTE r,
IN BYTE g,
IN BYTE b)
{
return (((ARGB) (b) << BlueShift) |
((ARGB) (g) << GreenShift) |
((ARGB) (r) << RedShift) |
((ARGB) (a) << AlphaShift));
}
Also take note, that HTML/CSS colors conform to ARGB.
However... when Microsoft, and the W3C switched to ARGB.. others did not.
OpenGL went with the RGBA format, and did not swap the red and blue, just added the alpha as the 4th byte above the blue, as in the original RGB ( or as in the 'old' GDI 32bit COLORREF with the alpha occuping the 'Reserved' 4th byte.)
So why am I worrying about this?
Well, I was 'mixing-in' the standard ruby library Comparble, so Sketchup::Color class objects could be compared to one another, and other objects, ie: integers and arrays that a coder might create for comparison sake. The simplest comparison is at the integer level, and it seemed to me that there was a math bug in the SU Color class.
So.. it turns out there is NO correct color integer, NOR color array, but instead 4 versions (editions) of each! ( RGB, RGB0, RGBA and ARGB ) The 1st being 24bit/3 element array; the following 3 being 32bit/4 element arrays.
Form ArrayFmt HexInteger Used by;
RGB [r,g,b] 0xbbggrr Win16
RGB0 [r,g,b,0] 0x00bbggrr Win32, GDI
RGBA [r,g,b,a] 0xaabbggrr OpenGL
ARGB [a,r,g,b] 0xaarrggbb Win32, GDI+,.NET, HTML/CSS
Form bits (MSB)--Binary Representation--(LSB)
RGB 24 bbbbbbbb gggggggg rrrrrrrr
RGB0 32 00000000 bbbbbbbb gggggggg rrrrrrrr
RGBA 32 aaaaaaaa bbbbbbbb gggggggg rrrrrrrr
ARGB 32 aaaaaaaa rrrrrrrr gggggggg bbbbbbbb
This greatly complicates implementing comparison, which may be why it was not done in the first place.
Also.. the idea of whether one color is greater or less than another, depends upon your viewpoint. If you like to think of color as having 'frequency magnitude', where red have lower freqs, and blue have higher freqs, than direct comparison of RGBA integers will work for you. On the other hand, most people (scientisits) refer to colors as having 'wavelength magnitude' where the blues have shorter wavelengths, and the colors have longer and longer wavelengths as you appraoch the red. So in the 2nd case you might prefer the ARGB; but a comparison of RGBA integers would give you an opposite result.
Oh.. we might think why not use a to_hash method and then the comparisons would be able to match up the rgba keys, but to complicate things further there are different types for the values: byteinteger, float 0.0-1.0, percent 0-100%.
It's looking like it's more trouble than it's worth.