编程语言您现在的位置是:首页 > 博客日志 > 编程语言

利用Imagick+php对图片进行优化(一)

<a href='mailto:'>微wx笑</a>的头像微wx笑 2022-03-21编程语言184 2 0关键字: php  imagick  

严格图片缩放顾名思义,将图片进行严格缩放到规定尺寸,允许图片变形。 严格切图 严格按照指定尺寸进行切图 大头贴举例说明,原图尺寸(1500*1000),需求尺寸(1000*800),利用该方法进行处

严格图片缩放

顾名思义,将图片进行严格缩放到规定尺寸,允许图片变形。 严格切图 严格按照指定尺寸进行切图 大头贴tgM无知

举例说明,原图尺寸(1500*1000),需求尺寸(1000*800),利用该方法进行处理时首先将图片以最小缩放的方式缩放,然后再将图片切割到需求尺寸,即先将图片缩成1200*800,再进行切割。tgM无知

自定义缩放

调用人员指定需求尺寸,同时指定缩放模式(按较大边进行缩放还是按照较小边进行缩放)……tgM无知

添加水印

顾名思义……tgM无知

实现示例

添加水印

代码

方案1(处理动态gif有问题):tgM无知

1
1 $im = new Imagick();//初始化一个IM对象
1
2 $im->readImage("/home/ben/xiao2.gif");//将带处理图片读入IM对象
1
3 $water = new Imagick();//再初始化一个IM对象,用于临时存储水印图
1
4 $water->readImage("/home/ben/watermark.png");//读入水印图
1
5 for($i = 0;$i < $im->getNumberImages();$i++)//由于gif是多帧图片,需要一帧帧处理
1
6 {
1
7 $im->setImageIndex($i);//设定当前待处理帧
1
8 $im->compositeimage($water,Imagick::COMPOSITE_OVER,0,0);//合并水印
1
9 }
1
10 //file_put_contents("/home/ben/result.gif",$im->getImagesBlob(),FILE_APPEND);//输出方案1
1
11 $im->writeImages("/home/ben/result3.gif",true);//输出方案2
1
<br>
方案2:较为完美的解决方案
1
2 function addWatermarkOnAllImgs($im,$water,$x,$y)
1
3 {
1
4 $format = strtolower($im->getImageFormat());
1
5 $color_transparent = new ImagickPixel("transparent"); //透明色
1
6 7 $dest = new Imagick();
1
8 foreach($im as $img)
1
9 {
1
10 $page = $img->getImagePage();//获得当前图片属性
1
11 $tmp = new Imagick();
1
12 $tmp->newImage($page['width'], $page['height'], $color_transparent, $format);//生成一张同大小的透明图片
1
13 $tmp->compositeImage($img, Imagick::COMPOSITE_OVER, $page['x'], $page['y']);//合并当前图片
1
14 $tmp->compositeImage($water,Imagick::COMPOSITE_OVER,$x,$y);//合并水印
1
15 16 $dest->addImage($tmp);//将图片添加进新的IM容器
1
17 $dest->setImagePage($tmp->getImageWidth(), $tmp->getImageHeight(), 0, 0);//设定图片的几何属性
1
18 $dest->setImageDelay($img->getImageDelay());//设定图片延迟
1
19 $dest->setImageDispose($img->getImageDispose());//设定动画处理方式
1
20 }
1
21 $dest->coalesceImages();//合并IM容器中的所有图片
1
22 $dest->writeImages("/home/ben/addwater.gif",true);
1
23 return true;
1
24 }
1
25 $src = new Imagick();
1
26 $src->readImage("/home/ben/xiao2.gif");
1
27 $water = new Imagick();
1
28 $water->readImage("/home/ben/watermark.png");
1
29 addWatermarkOnAllImgs($src,$water,0,0);
处理结果

1.原始图片tgM无知

利用Imagick+php对图片进行优化(一)
2.处理结果
利用Imagick+php对图片进行优化(一)tgM无知

                                         2.1 方案一
利用Imagick+php对图片进行优化(一)tgM无知

                                                2.2 方案二tgM无知

注意事项

从以上处理结果可以看出,如果不逐帧进行处理会造成水印时隐时现的现象,为此在处理多帧图片时必须注意以下几点:
(1)处理多帧图片时必须循环得到各帧图片,然后进行相关处理;
(2)输出图片时(writeImages或getImagesBlob)一定注意image的复数形式,不然只会得到当前一帧静态图片,而非动态gif动画。
(3)动画处理方式(disposal method):
a)None--不进行处理。选择此方式时,下一帧的内容会直接覆盖在当前帧的内容上面。
b)Restore to Background--恢复背景色。此选项会首先擦除当前帧的图像内容,然后恢复到背景色或背景图案(如果背景是透明的,就恢复成透明),接下来在显示下一帧的内容。此选项常用在背景透明的动画上。
c)Restore to Previous--恢复上一帧。此选项会擦除当前帧的内容,然后恢复上一帧的内容,接下来在显示下一帧的内容。
两种方案的比较:
从处理结果可以清楚的看出不同,其原因正如http://wxw850227.iteye.com/blog/402085中所述------动画的每一帧图片大小不一定相同,采用方案一会造成图片因添加水印位置的不统一而发生错乱tgM无知

gif图片调整大小

代码
1
function resizeImage($filename,$width,$height)
1
{
1
$src = new Imagick();
1
$src->readImage($filename);
1
$framenum = $src->getNumberImages();
1
if($framenum>1)
1
{
1
$format = strtolower($src->getImageFormat());//获得图片格式,备用
1
$dest = new Imagick();
1
$color_transparent = new ImagickPixel("transparent"); //透明色
1
foreach($src as $img)
1
{
1
$page = $img->getImagePage();
1
$tmp = new Imagick();
1
$tmp->newImage($page['width'], $page['height'], $color_transparent, $format);//在临时IM对象中生成一张同大小透明新图
1
$tmp->compositeImage($img, Imagick::COMPOSITE_OVER, $page['x'], $page['y']);//合并原图
1
$tmp->resizeimage($width,$height,Imagick::FILTER_UNDEFINED,0.75,false);//重设图片大小
1
$dest->addImage($tmp);//将处理后的图片放入输出IM对象中
1
$dest->setImagePage($tmp->getImageWidth(), $tmp->getImageHeight(), 0, 0);//设定当前图片大小
1
$dest->setImageDelay($img->getImageDelay());//设定图片延迟
1
$dest->setImageDispose($img->getImageDispose());//设定动画处理方式
1
}
1
$dest->coalesceImages();//合并所有图片
1
$dest->writeImages("/home/ben/resize.gif",true);
1
}
1
else
1
{
1
$src->resizeimage($width,$height,Imagick::FILTER_UNDEFINED,0.75,false);
1
$src->writeImages("/home/ben/resize.gif",true);
1
}
1
}
1
resizeImage("/home/ben/xiao.gif",200,200);
处理结果

利用Imagick+php对图片进行优化(一)tgM无知

注意事项

也许有人会说,简单的缩放干嘛搞这么复杂直接采用如下的方式逐帧缩放不就完了?tgM无知

1
for($i=0;$i<$framenum;$i++)
1
{
1
$src->setImageIndex($i);
1
$src->resizeimage($width,$height,Imagick::FILTER_UNDEFINED,0.75,false);
1
}

有人提出了对gif动画逐帧缩放时存在的问题
(1)透明动画的问题
(2)帧图片比显示尺寸小,并且有坐标控制的问题,直接缩小会使得动画完全乱掉
并给出了上述解决办法,故借鉴别人的繁琐但有效的处理方式。
附加几点注意事项:
1.resizeimage()可以利用第四个参数来增加模糊效果,=1相当于没有添加效果;<1,相当于锐化图片,使图片更清晰;>1,其值越大就会越模糊;=0时,是无穷大的模糊,也就是变成一片黑……0.75是一个经验值,利用该值可以调整绝大多数图片因缩放所带来的模糊。
2.有关resizeimage与scaleImage():二者均可以用于图片缩放,不同之处在于:Resizing the image changes the dimensions of the image without applying a transformation to the existing contents. Scaling the image will stretch the existing contents to the new dimensions.用事实说话吧:
如下图为用scale处理后的同一张图,与resize处理后的效果非常明显(够恶心的哈): 利用Imagick+php对图片进行优化(一)
3.一种错误的处理方式:
3.1 codetgM无知

1
$format = strtolower($src->getImageFormat());
1
$dest =new Imagick();
1
$color_transparent = new ImagickPixel("transparent"); //透明色
1
$src_page = $src->getImagePage();
1
$src_width = $src_page['width'];
1
$src_height = $src_page['height'];
1
$rate_w = $width/$src_width;
1
$rate_h = $height/$src_height;
1
foreach($src as $img)
1
{
1
$page = $img->getImagePage();
1
// $img->resizeimage($page['width']*$rate_w,$page['height']
1
*$rate_h,Imagick::FILTER_UNDEFINED,1,false);
1
// $img->resizeimage($width,$height,Imagick::FILTER_UNDEFINED,1,false);
1
$img->setImagePage($page['width']*$rate_w,$page['height']*$rate_h,$page['x']*$rate_w,$page['y']*$rate_h);
1
$page = $img->getImagePage();
1
$tmp = new Imagick();
1
$tmp->newImage($page['width'], $page['height'], $color_transparent, $format);
1
$tmp->compositeImage($img, Imagick::COMPOSITE_OVER, $page['x'], $page['y']);
1
// $tmp->resizeimage($width,$height,Imagick::FILTER_UNDEFINED,1,false);
1
$dest->addImage($tmp);
1
$dest->setImagePage($tmp->getImageWidth(), $tmp->getImageHeight(), 0, 0);
1
$dest->setImageDelay($img->getImageDelay());
1
$dest->setImageDispose($img->getImageDispose());
1
}
1
$dest->coalesceImages();
1
$dest->writeImages("/home/ben/zoomres1.gif",true);

3.2 处理结果
利用Imagick+php对图片进行优化(一)
3.3 原因分析
与可行代码的差异描述:
可行代码是将当前图片合并到一新的IM容器中,然后对该图片进行缩放,最后将该图片合并;上述代码的操作步骤为:先将当前图片进行缩放,再新建一个IM容器,将缩放后的图片合并到IM容器的透明图上,最后将所有图片合并。可以预见这样处理会发生坐标偏移,尝试用setImagePage来控制图片坐标,仍不对……原因未明~~tgM无知

大头贴效果 

明显可以看出缩放切割效果~tgM无知


tgM无知

转自:http://blog.sina.com.cn/s/blog_6bf82eb20100w5lr.htmltgM无知

本文为转载文章,版权归原作者所有,不代表本站立场和观点。

很赞哦! (9) 有话说 (0)

文章评论