On Wed, March 22, 2006 9:18 pm, brian dichiara wrote:
> Is there a way to check to see if a JPEG or PDF is color or
> black/white?
> Like a function or something?
There does not appear to be a built-in function that does that...
However, this hack should work:
function image_is_color($image){
for ($x = 0, $xmax = imagesx($image); $x < $xmax; $x++){
for ($y = 0, $ymax = imagesy($image); $y < $ymax; $y++){
$index = imagecolorat($image, $x, $y);
list($r, $g, $b) = imagecolorsforindex($image, $index);
//If all images are TrueColor, the preceding can be replaced with
// $r = ($index >> 16) & 0xFF;
// $g = ($index >> 8) & 0xFF;
// $b = $index & 0xFF;
// because in TrueColor the index is just the 24-bit color value
if ($r != $g || $g != $b) return true;
// You could add || $r != $b, but it's a tautology, no???
}
}
//If we made it here, EVERY damn pixel has R==G==B, so it's grayscale
return false;
}
NOTE:
This is NOT going to be fast, especially for large images, especially
for large gray-scale images, in which EVERY pixel will get checked
before we know it's grayscale.
If you have MOSTLY grayscale images and a few color, switch around the
true/false and the test and make it is_grayscale() so you can bail out
MUCH faster, when the first few pixels prove an image is NOT what you
usually have.
You could also set up a multi-threaded environment and run is_color
and is_grayscale and then time-out the one that takes forever... This
might be best if you have humoungous images and you are checking them
in a cron job or something.
Still, if you have an image that's all grayscale, and only the
top-right corner is color, or vice versa, you're gonna wait a long
time...
Hmmmm.
If it's NOT a TrueColor image, and imagecolorstotal() returns a
"small" number, then you could MUCH faster just do:
function is_color($image){
for ($index = 0, $total = imagecolorstotal($image); $index < $total;
$index++){
list($r, $g, $b) = imagecolorsforindex($image, $index);
if ($r != $g || $g != $b) return true;
}
return false;
}
Which then makes me think that maybe you should do:
function is_color($image){
$xmax = imagesx($image);
$ymax = imagesy($image);
$count = imagecolorstotal($image);
if ($count > ($xmax * $ymax)){
//call my first version, cuz the image is 'small' in x/y size
}
else{
//call my second version, cuz the image has few colors in palette
}
}
Some benchmarks could be done to refine the test that chooses between
the function bodies -- If imagecolorsforindex() is inherently
slower/faster than imagecolorat() + bit-shifting, then you'd want to
factor in the speed difference.
Have fun!
--
Like Music?
http://l-i-e.com/artists.htm
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php