Getting Red-Green-Blue from Hexadecimal Colors – PHP Bitwise

When working with CSS, it is common to use Hexadecimal Notation of colors, while on the back end, many PHP functions (like imagecolorallocate(), imagecolorclosest(), imagecolorexact() etc, require that you pass on colors as red, green and blue integers.

The below function can be helpful if you need to convert hexadecimal color literal to red, green and blue int values for use elsewhere. This function accepts hex, converts to RGB and stores the respective color values in three variables $red, $green and $blue variables passed by reference.

function get_rgb( $color , &$red , &$green , &$blue ) {
 
    if( ( ( int ) $color ) !== $color ) {
        //$color is string
        $color  = trim( $color , " \t\n\r#" );
 
        if( ctype_xdigit( $color ) && strlen( $color ) === 6 ) {
            //Convert to int
            $color  = ( int ) hexdec( $color );
        } else {
            return false;
        }
    }
 
    $red    = ( $color >> 16 ) & 0xFF;    //Red is the Left Most Byte
    $green  = ( $color >> 8 ) & 0xFF;     //Green is the Middle Byte
    $blue   = $color & 0xFF;              //Blue is the Right Most Byte
 
    return true;
}

The & 0xFF part in $red = ( $color >> 16 ) & 0xff; ensures that if input color is an integer (or hexadecimal integer literal) and it exceeds 0xFFFFFF (24 ON bits), the part of the integer exceeding the limit is overlooked and does not affect our RGB values. strlen( $color ) === 6 implements the same for string color literals.

trim( $color , " \t\n\r#" ) removes all spaces, new line characters (Windows, Mac and Linux), tab characters as well as # character from around the color hex.

The function returns true on success and false on failure caused by invalid color passed to the function. So, before using $red, $green and $blue variables in your script, its better to check the return value of the function

if( get_rgb( $color , $red , $green , $blue ) ) {
    work_with_colors( $red , $green , $blue );
}

Tests

I have tested get_rgb() with three different input patterns:

  • Hexadecimal representation of integers: 0xFF9933, or simply integers;
  • Hexadecimal Color String, starting with # symbol: #FF9933;
  • Hexadecimal Color String, without # symbol: FF9933;
//Test – 1
$color  = 0xFF9933;
get_rgb( $color , $red , $green , $blue );

//Test – 2
$color  = '#FF9933';
get_rgb( $color , $red , $green , $blue );

//Test – 3
$color  = 'FF9933';
get_rgb( $color , $red , $green , $blue );

//Same result for all of the above tests:
echo $red;      //255
echo $green;    //153
echo $blue;     //51

Leave a Reply