Appel Flap
Appel Flap

Reputation: 271

PHP - Get Brighttest Hex Color From Array With Hex Colors

Now I've been searching around online on how to do this, but there doesn't seem to be a single question/answer to this.

I'm using a script to get the 6 main colors from a given image.

function detectColors($image, $num, $level = 5)
{
    $level   = (int) $level;
    $palette = array();
    $size    = getimagesize($image);
    if (!$size) {
        return FALSE;
    }
    switch ($size['mime']) {
        case 'image/jpeg':
            $img = imagecreatefromjpeg($image);
            break;
        case 'image/png':
            $img = imagecreatefrompng($image);
            break;
        case 'image/gif':
            $img = imagecreatefromgif($image);
            break;
        default:
            return FALSE;
    }
    if (!$img) {
        return FALSE;
    }
    for ($i = 0; $i < $size[0]; $i += $level) {
        for ($j = 0; $j < $size[1]; $j += $level) {
            $thisColor       = imagecolorat($img, $i, $j);
            $rgb             = imagecolorsforindex($img, $thisColor);
            $color           = sprintf('%02X%02X%02X', (round(round(($rgb['red'] / 0x33)) * 0x33)), round(round(($rgb['green'] / 0x33)) * 0x33), round(round(($rgb['blue'] / 0x33)) * 0x33));
            $palette[$color] = isset($palette[$color]) ? ++$palette[$color] : 1;
        }
    }
    arsort($palette);
    return array_slice(array_keys($palette), 0, $num);
}

$img = 'https://gs2-sec.ww.prod.dl.playstation.net/gs2-sec/appkgo/prod/CUSA03041_00/15/i_2efe1b71a037233f60cec3b41a18d69c02bcff5fd0c895c212d44f37883dbaf8/i/icon0.png';
$palette = detectColors($img, 6, 5);
echo '<img src="' . $img . '" />';
echo '<table>';
foreach($palette as $color) {
  echo '<tr><td style="background:#' . $color . '; width:36px;"></td><td>#' . $color . '</td></tr>';
}
echo '</table>';

This will output a color palette:

enter image description here

What I would like to do with these colors, is finding out which one is the brighest, aka the dominant color, in this case the second color "CC0000". Of course excluding white #FFFFFF and black #000000.

My question being, how can I get the brightest color from an array of colors in PHP?

Upvotes: 2

Views: 835

Answers (2)

JonoJames
JonoJames

Reputation: 1223

Ok Hex colors work from darkest to lightest being 012345679ABCDEF and they broken up in 2 characters representing Red Green Blue that's why a RGB color value is is made up of 6 characters

So you need a function to to compare the values and return the highest . Im not using and array but you can compare 2 values at a time with this function and adjust it to use an array .

function GetBrightest($first_color,$Second_color) {
        //echo $first_color;
        //remove the hash #

        $first =  $a = str_replace('#', '', $first_color);
        $second =  $a = str_replace('#', '', $Second_color);

        $split_first = str_split($first, 2);
        $split_second = str_split($second, 2);

        print_r( $split_first);

        print_r( $split_second);

        //is red brighter
        $r = ( $split_first[0] > $split_second[0] ?  1: 0);
        $g = ( $split_first[1] > $split_second[1] ?  1: 0);
        $b = ( $split_first[2] > $split_second[2] ?  1: 0);


        //add the booleans
        $t = $r+$g+$b;



        if($t > 2 )
        {
                return $first_color;

        }
        else
        {
                return $Second_color;
        }



} $Color = GetBrightest('#aa4444','#ff3333'); echo $Color;

The comparison I have done here is a rough comparison so you could refine the method as 2 of the 3 array values could be bigger however if the difference is vast in one color it would make it brighter

FF0000 and 991111 in this function will return the second color because Green and Blue is brighter however the red is very bright in the first value .

So you can refine it from there ...

Upvotes: 1

Professor Abronsius
Professor Abronsius

Reputation: 33804

If I understood correctly then perhaps you could approach the problem like this?

function detectColors( $image, $num, $level = 5 ) {
    $level   = (int)$level;
    $palette = array();
    $details = array();# store the count of non black or white colours here ( see $exclusions )

    list( $width, $height, $type, $attr )=getimagesize( $image );
    if( !$type ) return FALSE;

    switch ( image_type_to_mime_type( $type ) ) {
        case 'image/jpeg':
            $img = imagecreatefromjpeg( $image );
        break;
        case 'image/png':
            $img = imagecreatefrompng( $image );
        break;
        case 'image/gif':
            $img = imagecreatefromgif( $image );
        break;
        default: return FALSE;
    }
    if( !$img ) return FALSE;

    /* Colours to not factor into dominance statistics */
    $exclusions=['000000','FFFFFF'];

    for( $i = 0; $i < $width; $i += $level ) {
        for( $j = 0; $j < $height; $j += $level ) {
            $colour             = imagecolorat( $img, $i, $j );
            $rgb                = imagecolorsforindex( $img, $colour );
            $key                = sprintf('%02X%02X%02X', ( round( round( ( $rgb['red'] / 0x33 ) ) * 0x33 ) ), round(round(($rgb['green'] / 0x33)) * 0x33), round(round(($rgb['blue'] / 0x33)) * 0x33));
            $palette[ $key ]    = isset( $palette[ $key ] ) ? ++$palette[ $key ] : 1;

            if( !in_array( $key, $exclusions ) ){
                /* add count of any non excluded colours */
                $details[ $key ] = isset( $details[ $key ] ) ? ++$details[ $key ] : 1;
            }
        }
    }
    arsort( $palette );

    /* prepare statistics for output */
    $output=new stdclass;
    $output->data=array_slice( array_keys( $palette ), 0, $num );
    $output->highest=max( $details );
    $output->lowest=min( $details );
    $output->dominant=array_search( $output->highest, $details );
    $output->recessive=array_search( $output->lowest, $details );


    return $output;
}



$img = 'https://gs2-sec.ww.prod.dl.playstation.net/gs2-sec/appkgo/prod/CUSA03041_00/15/i_2efe1b71a037233f60cec3b41a18d69c02bcff5fd0c895c212d44f37883dbaf8/i/icon0.png';
$palette = detectColors( $img, 6, 5 );


$html=[];
foreach( $palette->data as $colour ) $html[]=sprintf( '<tr><td style="background:#%1$s; width:200px; height:1rem; " >#%1$s</td></tr>', $colour );

printf('
    <p>Analysing: %1$s</p>
    <img src="%1$s" />
    <table>%2$s</table>
    <ul>
        <li>Dominant colour: %3$s - count: %4$d</li>
        <li>Recessive colour: %5$s - count: %6$d</li>
    </ul>',
    $img,
    implode( PHP_EOL, $html ),
    $palette->dominant,
    $palette->highest,
    $palette->recessive,
    $palette->lowest
);

Outputs:

Dominant colour: CC0000 - count: 3032
Recessive colour: 333366 - count: 1

Is that more or less what you were asking?

Upvotes: 1

Related Questions