说明:
由于动态gif是由多张静态图片组成的,所以生成缩略图时要循环遍历每一张图片,对每张图片分别进行resize,最后再合并到一起。
我没深入研究gif图片的格式,以下是根据实际测试得出的一些结论:
(1)可根据gif图片的头部特殊字符串判断是否是动态gif图片(is_animation函数)
(2)动态gif图片第0帧貌似是背景图,可以根据此图得出图片最大宽度和高度,然后得到一个压缩比率,其他帧都以此压缩比率进行压缩。
(3)动态gif图片第1帧貌似是被保留的,用来存储背景图resize后的图片(实际上就是静态缩略图),所以在执行resize操作时要把此帧排除,不然就等于把缩略图又压缩了一次,观察到现象就是一张被resize了两次的很小的缩略图。
(4)MagickWriteImages()只比MagickWriteImage()函数多了一个s,用来把多张图片写到一个图片中(第三个参数必须是true)
(5)MagickResetIterator()和MagickNextImage()可用来实现循环迭代
(6)生成的缩略图会有略微的错位变形
 

 
  
  1. $magickwand = NewMagickWand(); 
  2. MagickReadImage($magickwand$src); 
  3. $type  = MagickGetImageFormat($magickwand); 
  4. $src_w = MagickGetImageWidth($magickwand); 
  5. $src_h = MagickGetImageHeight($magickwand); 
  6. $src = '/data1/cache/src.gif' 
  7. $dst = '/data1/cache/dst.gif'
  8. $width = 160; 
  9. $height = 120; 
  10. if($type=='GIF'){ 
  11.     if(is_animation($src)) 
  12.     { 
  13.         scale_GIF($magickwand$width$width); 
  14.         MagickWriteImages($magickwand$dst, true); 
  15.         DestroyMagickWand($magickwand);     
  16.     } 
  17. }             
  18.  
  19. function is_animation($src
  20.     $fp=fopen($src'rb'); 
  21.     $p_w_picpath_head = fread($fp,1024); 
  22.     fclose($fp); 
  23.     return preg_match('/'.chr(0x21).chr(0xff).chr(0x0b).'NETSCAPE2.0/'$p_w_picpath_head) ? true : false; 
  24.  
  25. function scale_GIF(&$magickwand$dst_width$dst_height
  26.     MagickResetIterator($magickwand); 
  27.     $i = 0; 
  28.     do
  29.         $src_w = MagickGetImageWidth($magickwand); 
  30.         $src_h = MagickGetImageHeight($magickwand); 
  31.         if($i==0) 
  32.         { 
  33.             $ratio_w = doubleval($src_w) / doubleval($dst_width); 
  34.             $ratio_h = doubleval($src_h) / doubleval($dst_height);     
  35.             $ratio   = $ratio_w > $ratio_h ? $ratio_w : $ratio_h
  36.             $width   = floor$src_w / $ratio); 
  37.             $height  = floor$src_h / $ratio);                 
  38.             if ($width>=$src_w || $height>=$src_h) { return true; }                 
  39.         } 
  40.         if($i!=1){ 
  41.             $width   = floor$src_w / $ratio); 
  42.             $height  = floor$src_h / $ratio); 
  43.             //echo "$i:$src_w,$src_h,$dst_width, $width, $height<br>"; 
  44.             if($width && $height) { 
  45.                 $r = MagickResizeImage($magickwand$width$height, MW_LanczosFilter, 1.0); 
  46.             } 
  47.         } 
  48.         $i++; 
  49.     }while(MagickNextImage($magickwand)); 
  50.     return true;