How would I be able to detect that an image is blank (only of a single, arbitrary color or, with a gif, frames of random arbitrary colors) using PHP and/or imagemagick?
I think this is what I'm going to try: http://www.php.net/manual/en/function.imagecolorat.php#97957
You can check the image inside of PHP using imagecolorat (this may be slow, but it works):
function isPngValidButBlank($filename) {
$img = imagecreatefrompng($filename);
if(!$img)
return false;
$width = imagesx($img);
$height = imagesy($img);
if(!$width || !$height)
return false;
$firstcolor = imagecolorat($img, 0, 0);
for($i = 0; $i < $width; $i++) {
for($j = 0; $j < $height; $j++) {
$color = imagecolorat($img, $i, $j);
if($color != $firstcolor)
return false;
}
}
return true;
}
http://www.php.net/manual/en/function.imagecolorstotal.php gives you the amount of colors in an image. Hmm, in my demo it doesn't seem to work, sorry :( an image i created (fully red, 20x20 pixels) gives 0 colors for PNG and 3 colors for GIF.
Ok: http://www.dynamicdrive.com/forums/showpost.php?p=161187&postcount=2
look at the 2nd piece of code. Tested here: http://www.pendemo.nl/totalcolors.php
Kevin's solution can be sped up using random sampling. If you have some idea of the percentage of pixels that should be different from the background (assuming you aren't dealing with lots of images with only 1 different pixel), you can use the Poisson distribution:
probability of finding a nonblank pixel = 1 - e^(-n*p)
where n is the number of samples to try, and p is the percentage of pixels expected to be nonblank. Solve for n to get the appropriate number of samples to try:
n = -log(1 - x) / p
where x is the desired probability and log is natural log. For example, if you are reasonably sure that 0.1% of the image should be nonblank, and you want to have a 99.99% chance of finding at least one nonblank pixel,
n = -log(1-.9999)/.001 = 9210 samples needed.
Much faster than checking every pixel. To be 100% sure, you can always go back and check all of them if the sampling doesn't find any.
For anyone using Imagick to try and achieve this, the getImageColors() method did the trick.
https://www.php.net/manual/en/imagick.getimagecolors.php
$img = new Imagick();
$img->readImage($image);
$colors = $img->getImageColors();
if(!$colors > 1) {
return false;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With