# Getting color information from an image

I am working on a site that themes itself based on images / logos. I have made a utility class that gets the colors from an image, shown below. I am fairly new to OOP with PHP, and I'm looking for feedback on what I could improve with the following. It is still in beta, so image-handling is a little sketchy and could use some work.

Image Used:

Class:

class Image {
private $_hex = array(); private$_size = array();
private $_topThree = array(); private$_im, $_mostCommon,$_minDem, $_tempHex,$_uniqueHex;

public function __construct($image) {$ext = explode('.',$image);$ext = end($ext); if ($ext === 'png') {
$this->_im = imagecreatefrompng($image);
} elseif ($ext === 'jpg' ||$ext === 'jpeg') {
$this->_im = imagecreatefromjpeg($image);
} else {
die('The supplied extension is not supported. Supported formats include: jpg, jpeg, and png.');
}
$this->_size = getimagesize($image);
$this->setHex(); } public function showAll() { foreach($this->_uniqueHex as $k) { echo '<div style="background-color:'.$k.'; width:100%; height:30px;">'.$k.'</div>'; } } public function getMostCommon() {$this->mostCommon($this->_hex); return$this->_mostCommon;
}

public function getTop() {
$this->_tempHex =$this->_hex;
$counted = array_count_values($this->_tempHex);
arsort($counted);$i = 0;
foreach ($counted as$k => $v) { if ($i < 3) {
$this->_topThree[$i] = $k; }$i++;
}
return $this->_topThree; } public function showTop() { if (empty($this->_topThree)) {
$this->getTop(); } foreach($this->_topThree as $k) { echo '<div style="background-color:'.$k.'; width:100%; height:30px;">'.strtoupper($k).'</div>'; } } ######################### ### PRIVATE FUNCTIONS ### ######################### private function setHex() {$x = 0;
$y = 0;$this->_minDem = min($this->_size[0],$this->_size[1]);
// Get RGB pixel by pixel
while ($x <$this->_minDem) {
$colors = imagecolorat($this->_im, $x,$y);
$r = ($colors >> 16) & 0xFF;
$g = ($colors >> 8) & 0xFF;
$b =$colors & 0xFF;
// Convert RGB to Hex
$this->_hex[] =$this->toHex($r,$g, $b);$x++;
$y++; }$this->removeWhiteBlack($this->_hex);$this->_uniqueHex = array_unique($this->_hex); } private function removeWhiteBlack($array) {
$i = 0; foreach($array as $k) {$k = strtolower($k); if ($k === '#ffffff' || $k === '#000000') { unset($this->_hex[$i]); }$i++;
}
}

private function mostCommon() {
$counted = array_count_values($this->_hex);
arsort($counted);$this->_mostCommon = key($counted); } private function toHex($r, $g=-1,$b=-1) {
(is_array($r) && sizeof($r) == 3) ? list($r,$g, $b) =$r : NULL;
$r = intval($r); $g = intval($g);
$b = intval($b);
$r = dechex($r<0?0:($r>255?255:$r));
$g = dechex($g<0?0:($g>255?255:$g));
$b = dechex($b<0?0:($b>255?255:$b));
$color = (strlen($r) < 2?'0':'').$r;$color .= (strlen($g) < 2?'0':'').$g;
$color .= (strlen($b) < 2?'0':'').$b; return '#'.$color;
}
}


## Usage:

$image = new Image('FGC.png');$topThree = $image->getTop();$image->showTop();
echo $image->getMostCommon(); echo '<pre>', print_r($topThree, true), '</pre>';

## Abstract common styles

In the loop of Image::showAll() each <div> contains three styles, the latter two being redundant. Those could be moved out to a <style> tag - either with a ruleset for div or other selector like a class name. In case performance/bandwidth is a concern this can decrease the amount of data returned by ~23%.

## Skip white and black

Instead of calling removeWhiteBlack() the code could simply not add white and black to the array.

### Array syntax

There isn't anything wrong with using array() but as of the time of writing, PHP has Active support for versions 8.0 and 7.4, and since PHP 5.4 arrays can be declared with short array syntax (PHP 5.4) - i.e. [].

### Converting RGB to Hex values

It looks like the code within Image::toHex() was pasted from an online source like this one. There are other techniques, many of which are shorter - e.g. using sprintf(). See answers to this SO post for simpler alternatives (except the answer by Rajarshi Das since that is nearly identical to the current code).