Reputation: 11649
I am writing an image search engine, which allows users to search by colour. As part of this, I need to determine whether the image is grayscale (contains only black, white or shades of grey) or contains any color.
How can I detect if the image contains any pixels outside of black, white and shades of grey?
Upvotes: 1
Views: 3772
Reputation: 41
I propose the following function. The way it works is only to find the similarity of the R-G-B value in pixels. If there is only one pixel whose RGB value is different, it could be a color image. However, it is recommended to insert the resize_uploaded()
function to save time.
function detect_greyscale($source_file)
{
$im = resize_uploaded($source_file);
$imgw = imagesx($im);
$imgh = imagesy($im);
$count_grey = '';
$count_color = '';
for ($i=0; $i<$imgw; $i++)
{
for ($j=0; $j<$imgh; $j++)
{
$rgb = ImageColorAt($im, $i, $j);
$rr = ($rgb >> 16) & 0xFF;
$gg = ($rgb >> 8) & 0xFF;
$bb = $rgb & 0xFF;
if($rr == $gg and $rr == $bb and $bb == $gg)
{
$count_grey++;
}
else
{
$count_color++;
}
}
}
imagedestroy($im);
if($count_color>0)
{
return 0;
}
return 1;
}
Upvotes: 1
Reputation: 736
Depending on which raster image suite is installed on the server, you could use those tools for a simpler and more exact answer than Pekka provides here. Whether this is speedier is an open argument (see note below).
In the ImageMagick sample (and link) below, the recommendation is to:
convert the image to HSL and then output verbose information ("identify" statistics)
Analyzing the verbose information gives you the answer to your question; hence exact, simple, and no need to make guesses about "near" grey images. It also provides other data that you may be able to use, depending on your workflow and needs.
Source: http://www.imagemagick.org/discourse-server/viewtopic.php?t=19580
I doubt that this is faster than Pekka's solution, because converting the image will essentially loop through the pixels anyway.
So, Pekka's answer for speed. This answer for precision.
Upvotes: 2
Reputation: 449385
You'd have to walk through every pixel using imagecolorat()
(see example #2).
Grayscale colours will have the same value for Red, Green, and Blue. If you find a pixel where the values differ, it's an image that contains a colour (at least technically - with a colour like RGB(100,102,103)
it will look grey to the human eye.).
Upvotes: 5