Bookmark and Share

Lee's 程序人生

HTML CSS Javascript XML AJAX ATLAS C# C++ 数据结构 软件工程 设计模式 asp.net Java 数字图象处理 Sql 数据库
  博客园  :: 首页  :: 新随笔  :: 联系 :: 管理

使用Imagick来”resize” 和 “crop” GIF动画

Posted on 2010-05-02 23:22  analyzer  阅读(2028)  评论(0编辑  收藏  举报

转自:http://blog.terry39.com/?p=51

 对GIF动画进行缩小操作时,需要逐帧的缩小,这里会碰到几个比较麻烦的问题:

1、透明动画的问题
2、帧图片比显示尺寸小,并且有坐标控制的问题,直接缩小会似的动画完全乱掉

针对第一个问题,首先要建立一个透明的目标图片对象
$image = new Imagick();
$image->newImage($width,$height, $color, ‘gif’);
其中 $color = new ImagickPixel(“transparent”); 实际上是建立了一个透明色。

针对第二个问题,一开始我也是循环了GIF中每个图片对象,发现尺寸大小不一样,看API手册里只有 getImageWidth 和getImageHeight 这两个方法是和尺寸有关的,而没有关于获得坐标 position 的方法;只能一个一个的试,最后发现是用 getImagePage 获得的一个数组,里面包含了 width, height, x, y 这4个字段,其中width和height分别是图象的显示尺寸,并非图象的尺寸,而图象的尺寸是用getImageWidth和getImageHeight来获得,可能比图象的显示尺寸小;还有两个数据 x和y 分别是当前图象在显示区域内的坐标;不知道这个 Image Page 如何翻译,也许应该是层的概念;这个时候就可以计算出帧图片正确的显示内容。

原图效果

缩小或切割后
 

这里给出ImagickResizeImage函数

  1. <?php
  2.  
  3. /**
  4.  * 使用ImageMagick库缩放图片
  5.  *
  6.  * @param string $srcFile  源图片路径
  7.  * @param string $destFile 目标文件路径
  8.  * @param int $new_w 新的宽度
  9.  * @param int $new_h 新的高度
  10.  * @param bool $trim 是否切割图片
  11.  *
  12.  * @version 1.0
  13.  * @update 2007-04-03 23:09
  14.  * @author terry39
  15.  *
  16.  */
  17. function ImagickResizeImage($srcFile,$destFile,$new_w,$new_h, $trim=false)
  18. {
  19. if($new_w <= 0 || $new_h <= 0 || !file_exists($srcFile)) return false;
  20. $src = new Imagick($srcFile);
  21. $image_format = strtolower($src->getImageFormat());
  22. if($image_format != 'jpeg' && $image_format != 'gif' && $image_format != 'png' && $image_format != 'jpg') return false;
  23.  
  24. $src_page = $src->getImagePage();
  25.  
  26. //如果是 bbsposts 目录里的图片文件,这加入水印
  27. if(strpos($destFile, 'bbsposts') !== false){
  28.  
  29. //先算出最终缩略图的尺寸
  30. $src_w = $src_page['width'];
  31. $src_h = $src_page['height'];
  32.  
  33. $rate_w  = $new_w / $src_w;
  34. $rate_h  = $new_h / $src_h;
  35.  
  36. $rate    = (!$trim && $rate_w < $rate_h) || ($trim && $rate_w > $rate_h) ? $rate_w : $rate_h;
  37. $rate = $rate > 1 ? 1 : $rate;
  38. $thumb_w = round($src_w * $rate);
  39. $thumb_h = round($src_h * $rate);
  40.  
  41. //确定使用对应尺寸的水印图片
  42. $watermask = true;
  43. if($thumb_w >= 300 && $thumb_h >= 300){
  44. $watermaskfile = "images/watermask/1.png";
  45. }else if($thumb_w >= 100 && $thumb_h >= 100){
  46. $watermaskfile = "images/watermask/2.png";
  47. }else{
  48. $watermask = false;
  49. $watermaskfile = '';
  50. }
  51. if($watermask){
  52. $water = new Imagick($watermaskfile);
  53. $water_page = $water->getImagePage();
  54. $water_w = $water_page['width'];
  55. $water_h = $water_page['height'];
  56. }
  57. }
  58.  
  59. //如果是 jpg jpeg gif
  60. if($image_format != 'gif'){
  61. $dest = $src;
  62. if(!$trim){
  63. $dest->thumbnailImage($new_w, $new_h, true);
  64. }else{
  65. $dest->cropthumbnailImage($new_w, $new_h);
  66. }
  67. if($watermask) $dest->compositeImage($water, Imagick::COMPOSITE_OVER, $dest->getImageWidth() - $water_w, $dest->getImageHeight() - $water_h);
  68.  
  69. $dest->writeImage($destFile);
  70. $dest->clear();
  71. //gif需要以帧一帧的处理
  72. }else{
  73. $dest = new Imagick();
  74. $color_transparent = new ImagickPixel("transparent"); //透明色
  75. foreach($src as $img){
  76. $page = $img->getImagePage();
  77. $tmp = new Imagick();
  78. $tmp->newImage($page['width'], $page['height'], $color_transparent, 'gif');
  79. $tmp->compositeImage($img, Imagick::COMPOSITE_OVER, $page['x'], $page['y']);
  80. if(!$trim){
  81. $tmp->thumbnailImage($new_w, $new_h, true);
  82. }else{
  83. $tmp->cropthumbnailImage($new_w, $new_h);
  84. }
  85. if($watermask) $tmp->compositeImage($water, Imagick::COMPOSITE_OVER, $tmp->getImageWidth() - $water_w, $tmp->getImageHeight() - $water_h);
  86. $dest->addImage($tmp);
  87. $dest->setImagePage($tmp->getImageWidth(), $tmp->getImageHeight(), 0, 0);
  88. $dest->setImageDelay($img->getImageDelay());
  89. $dest->setImageDispose($img->getImageDispose());
  90.  
  91. }
  92. $dest->coalesceImages();
  93. $dest->writeImages($destFile, true);
  94.  
  95. $dest->clear();
  96. }
  97. }
  98. ?>
我要啦免费统计