Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting blank generated images with php?

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

like image 406
Kenneth Rapp Avatar asked May 06 '11 19:05

Kenneth Rapp


4 Answers

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;
}
like image 162
Kevin Borders Avatar answered Nov 17 '22 18:11

Kevin Borders


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

like image 25
Joshua - Pendo Avatar answered Nov 17 '22 18:11

Joshua - Pendo


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.

like image 2
Aaron Koller Avatar answered Nov 17 '22 17:11

Aaron Koller


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;
    }
like image 2
knutter539 Avatar answered Nov 17 '22 17:11

knutter539