I'm running an image collection site www.wonkeypics.com

It's a real simple setup, nothing fancy but imagecache keeps destroying the animated images. Even when nothing needs to be done to them it processes them anyways. How can I make it skip over anything with a .gif file extention?

Thanks :)

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

ghankstef’s picture

I am running into this too. I'm going to try to see if there is a way to detect the animated gif. Here is an idea that could be used with theme_imagecache with the idea that you return or skip imagecache if its an animated gif:

http://stackoverflow.com/questions/280658/can-i-detect-animated-gifs-usi...

ShaneOnABike’s picture

Component: imagecache_image module » Code
Category: support » feature
Status: Active » Needs review

I was looking for something similiar. I kind of wonder if we couldn't put a patch in theme_imagecache that has a flag (admin) to ignore animated GIFs. Cropping these images completely losses the animation (which makes sense but there's no way around that). This might not be ideal since it does ignore the scaling aspect of things :S

Here's the code for anyone else that needs it.

theme_imagecache

/**
 * Create and image tag for an imagecache derivative
 *
 * @param $presetname
 *   String with the name of the preset used to generate the derivative image.
 * @param $path
 *   String path to the original image you wish to create a derivative image
 *   tag for.
 * @param $alt
 *   Optional string with alternate text for the img element.
 * @param $title
 *   Optional string with title for the img element.
 * @param $attributes
 *   Optional drupal_attributes() array. If $attributes is an array then the
 *   default imagecache classes will not be set automatically, you must do this
 *   manually.
 * @param $getsize
 *   If set to TRUE, the image's dimension are fetched and added as width/height
 *   attributes.
 * @return
 *   HTML img element string.
 */
function cinemapolitica_imagecache($presetname, $path, $alt = '', $title = '', $attributes = NULL, $ge$
  if (is_null($path)) {
    return '';
  }
  // Check is_null() so people can intentionally pass an empty array of
  // to override the defaults completely.
  if (is_null($attributes)) {
    $attributes = array('class' => 'imagecache imagecache-'. $presetname);
  }

  // Check if it's an animated gif (don't create imagecache if so)
  $create_cache = TRUE;
  $data = @getimagesize($path);
  if (isset($data) && is_array($data) && $data['mime'] == 'image/gif') {
        $create_cache = !cinemapolitica_is_animated($path);
  }

  if ($create_cache && $getsize && ($image = image_get_info(imagecache_create_path($presetname,
$path)))) {
    $attributes['width'] = $image['width'];
    $attributes['height'] = $image['height'];
  }

  $attributes = drupal_attributes($attributes);
  $imagecache_url = ($create_cache) ? imagecache_create_url($presetname, $path) : '/'.$path;
  return '<img src="'. $imagecache_url .'" alt="'. check_plain($alt) .'" title="'. check_plain($title)$
}

imagecache_is_animated_gif($filename) - new function

/**
 *
 * Determine if the image is animated
 *
 * @param
 *  $filename - name of file to path
 * @return
 *  TRUE - if it is animated
 **/
function imagecache_is_animated($filename) {
  $filecontents=file_get_contents($filename);

  $str_loc=0;
  $count=0;
  while ($count < 2) # There is no point in continuing after we find a 2nd frame
  {
    $where1=strpos($filecontents,"\x00\x21\xF9\x04",$str_loc);
    if ($where1 === FALSE){
        break;
    } else {
       $str_loc=$where1+1;
       $where2=strpos($filecontents,"\x00\x2C",$str_loc);
        if ($where2 === FALSE) {
          break;
        } else {
          if ($where1+8 == $where2) {
             $count++;
           }
           $str_loc=$where2+1;
        }
    }
  }
  return ($count > 1);
}
joruffin’s picture

FileSize
1.65 KB

Patch adapted from above code against imagecache 6.x-2.0-beta12.

truyenle’s picture

Same issue and the patch work for me.

sandrewj’s picture

To me it looks like the patch checks the contents of any file sent to it. Can we add a check at the start that the file is a gif file? This would also avoid the unlikely situation where a PNG or JPG is passed that happens to have the "correct" string. All GIF files start with the string "GIF", supposedly.

sandrewj’s picture

Status: Needs review » Needs work

Looking into this issue more, it seems like the imagemagic toolkit can support resizing animated gifs. #1115658: Animated GIF image gets broken on resize with ImageMagick toolkit

The proposed patch above would change the default behavior of imagecache. Currently imagecache does its best to generate the altered image or returns a 500 response if unable to. It also returns a 403 response if the file is not registered as an image.

I think it would be ok to return a 500 "internal server error" message if imagecache knows the image won't actually be generated correctly (even though a "valid" image is created) There should be an admin option for marking animated gifs as unsupported in that case.

For the "is_animated" function, I think it should include the filetype check inside the function.

function imagecache_is_animated($filename) {
 
 $filecontents=file_get_contents($filename);
 if (strpos($filecontents, "GIF") ==0){
   $str_loc=0;
   $count=0;
   while ($count < 2) # There is no point in continuing after we find a 2nd frame
   {
     $where1=strpos($filecontents,"\x00\x21\xF9\x04",$str_loc);
     if ($where1 === FALSE){
         break;
     } else {
        $str_loc=$where1+1;
        $where2=strpos($filecontents,"\x00\x2C",$str_loc);
         if ($where2 === FALSE) {
           break;
         } else {
           if ($where1+8 == $where2) {
              $count++;
            }
            $str_loc=$where2+1;
         }
     }
   }
   return ($count > 1);
  }
  return false;
}

the results should be used in imagecache_create_url to bypass all other work that imagecache would do.

function imagecache_create_url($presetname, $filepath, $bypass_browser_cache = FALSE, $absolute = TRUE) {
if (imagecache_is_animated($filepath)){
return $filepath;
}
...

I haven't tested the above code, and I think it isn't an ideal solution, but it would give a more compact solution to the question "how can I make imagecache produce links to the original instead of a derivative when dealing with animated gifs?"

fizk’s picture

Status: Needs work » Closed (fixed)

Please reopen if this is still an issue with ImageCache 6.x-2.0-rc1.

tostinni’s picture

Working great with RC1, however you have to use imagemagick instead of GD2.

Manuel Garcia’s picture

Just confirming that on RC1, using imagemagick the animation is kept, no need to patch anything.

botanic_spark’s picture

Issue summary: View changes

I can confirm that imagemagick solves the problem.

darkdim’s picture

bit corrected code