Skip to content

Instantly share code, notes, and snippets.

@RonenNess
Created December 19, 2021 22:26
Show Gist options
  • Save RonenNess/87a5b3957f4d720d2075fb57679240b8 to your computer and use it in GitHub Desktop.
Save RonenNess/87a5b3957f4d720d2075fb57679240b8 to your computer and use it in GitHub Desktop.
A tiny utility to pack a color value in a single byte,
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
/// <summary>
/// Colors enum, can be packed in 4 bits.
/// </summary>
public enum ColorsEnum
{
White,
Red,
Green,
Blue,
Yellow,
Purple,
Teal,
Orange,
Brown,
Silver,
Gold,
Bronze,
Pink,
Violet,
Lime,
PureBlack,
// 4 bits
_LastColorVal,
_All,
}
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
/// <summary>
/// Represent a color as a single byte.
/// 4 bits = color hue, represented by ColorsEnum.
/// </summary>
public struct PackedColor
{
/// <summary>
/// The packed byte value
/// </summary>
public byte Value;
/// <summary>
/// Set / get color component.
/// </summary>
public ColorsEnum Color
{
get => (ColorsEnum)(Value & 0b1111);
set => Value = (byte)((Value & 0b11110000) | (int)value);
}
/// <summary>
/// Set / get colors shade.
/// Must be value between 0 and 7, that fit in 3 bits.
/// </summary>
public byte Darkness
{
get => (byte)((Value >> 4) & 0b111);
set => Value = (byte)((Value & 0b10001111) | (int)(value << 4));
}
/// <summary>
/// Optional additional flag.
/// </summary>
public bool AdditionalFlag
{
get => (Value & 0b10000000) != 0;
set => Value = (byte)((Value & 0b01111111) | (value ? 0b10000000 : 0));
}
}
@RonenNess
Copy link
Author

This solution is based on a set of base colors for hue, darkness factor (0-7), and additional optional bit that can be used for opacity etc.
For example, for dark red you can set the Color value to 'Red', and darkness to 6 or7.

Its better IMO than coding colors with 2 bits per component (RGB) + extra bit for opacity, because with the system above you can choose the actual hue of 'Red' and can pick a better looking palette, and the 2 bits solution ends up with not very charismatic palette that ends up with lots of very similar looking colors.

This code only packs the values in byte, for actual color value you need to do translation to whatever object you use to represent colors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment