php扩展imagick的说明和实例,如:添加水印、图片剪裁、图片大小等 ImageMagick
分类:PHP_Python| 发布:佚名| 查看:565 | 发表时间:2014/11/30
PHP建图通常都用GD库,因为是内置的不需要在服务器上额外安装插件,所以用起来比较省心,但是如果你的程序主要的功能就是处理图像,那麼就不建议用GD了,因为GD不但低效能而且能力也比较弱,佔用的系统资源也颇多,另外GD的creatfrom也有bug,而imagick却是一个很好的替代品,为此最近把我的一个项目由GD改成了imagick,但是改完之后出现了一些状况在此分享给大家.
首先说一下我这边出现的状况:
状况一:需要重写图像操作class
状况二:imagick多线程时会导致cpu使用率暴增到100%
在此顺便提一下imagick在centos6.4的安装方法:
1、安装ImageMagick
代码如下:
001 | wget upload/2014/11/201411141106431410.gif'); |
002 | $Imagick ->resize_to(100,100, 'scale_fill' ); |
003 | $Imagick ->add_text( '1024i.com' ,10,20); |
004 | $Imagick ->add_watermark( '1024i.gif' ,10,50); |
005 | $Imagick ->save_to( 'x.gif' ); |
008 | define( 'CLASS_IMAGICK' ,TRUE); |
013 | public function __construct(){} |
015 | public function __destruct(){ |
016 | if ( $this ->image!==null){ $this ->image->destroy();} |
019 | public function open( $path ){ |
020 | if (! file_exists ( $path )){ |
024 | $this ->image= new Imagick( $path ); |
026 | $this ->type= strtolower ( $this ->image->getImageFormat()); |
028 | $this ->image->stripImage(); |
034 | public function crop( $x =0, $y =0, $width =null, $height =null){ |
035 | if ( $width ==null) $width = $this ->image->getImageWidth()- $x ; |
036 | if ( $height ==null) $height = $this ->image->getImageHeight()- $y ; |
037 | if ( $width <=0 || $height <=0) return ; |
038 | if ( $this ->type== 'gif' ){ |
040 | $canvas = new Imagick(); |
041 | $images = $image ->coalesceImages(); |
042 | foreach ( $images as $frame ){ |
044 | $img ->readImageBlob( $frame ); |
045 | $img ->cropImage( $width , $height , $x , $y ); |
046 | $canvas ->addImage( $img ); |
047 | $canvas ->setImageDelay( $img ->getImageDelay()); |
048 | $canvas ->setImagePage( $width , $height ,0,0); |
051 | $this ->image= $canvas ; |
053 | $this ->image->cropImage( $width , $height , $x , $y ); |
074 | public function resize_to( $width =100, $height =100, $fit = 'center' , $fill_color = array (255,255,255,0)){ |
077 | if ( $this ->type== 'gif' ){ |
079 | $canvas = new Imagick(); |
080 | $images = $image ->coalesceImages(); |
081 | foreach ( $images as $frame ){ |
083 | $img ->readImageBlob( $frame ); |
084 | $img ->thumbnailImage( $width , $height ,false); |
085 | $canvas ->addImage( $img ); |
086 | $canvas ->setImageDelay( $img ->getImageDelay()); |
089 | $this ->image= $canvas ; |
091 | $this ->image->thumbnailImage( $width , $height ,false); |
095 | if ( $this ->type== 'gif' ){ |
097 | $images = $image ->coalesceImages(); |
098 | $canvas = new Imagick(); |
099 | foreach ( $images as $frame ){ |
101 | $img ->readImageBlob( $frame ); |
102 | $img ->thumbnailImage( $width , $height ,true); |
103 | $canvas ->addImage( $img ); |
104 | $canvas ->setImageDelay( $img ->getImageDelay()); |
107 | $this ->image= $canvas ; |
109 | $this ->image->thumbnailImage( $width , $height ,true); |
113 | $size = $this ->image->getImagePage(); |
114 | $src_width = $size [ 'width' ]; |
115 | $src_height = $size [ 'height' ]; |
120 | if ( $src_width * $height > $src_height * $width ){ |
121 | $dst_height = intval ( $width * $src_height / $src_width ); |
122 | $y = intval (( $height - $dst_height )/2); |
124 | $dst_width = intval ( $height * $src_width / $src_height ); |
125 | $x = intval (( $width - $dst_width )/2); |
128 | $canvas = new Imagick(); |
129 | $color = 'rgba(' . $fill_color [0]. ',' . $fill_color [1]. ',' . $fill_color [2]. ',' . $fill_color [3]. ')' ; |
130 | if ( $this ->type== 'gif' ){ |
131 | $images = $image ->coalesceImages(); |
132 | foreach ( $images as $frame ){ |
133 | $frame ->thumbnailImage( $width , $height ,true); |
134 | $draw = new ImagickDraw(); |
135 | $draw ->composite( $frame ->getImageCompose(), $x , $y , $dst_width , $dst_height , $frame ); |
137 | $img ->newImage( $width , $height , $color , 'gif' ); |
138 | $img ->drawImage( $draw ); |
139 | $canvas ->addImage( $img ); |
140 | $canvas ->setImageDelay( $img ->getImageDelay()); |
141 | $canvas ->setImagePage( $width , $height ,0,0); |
144 | $image ->thumbnailImage( $width , $height ,true); |
145 | $draw = new ImagickDraw(); |
146 | $draw ->composite( $image ->getImageCompose(), $x , $y , $dst_width , $dst_height , $image ); |
147 | $canvas ->newImage( $width , $height , $color , $this ->get_type()); |
148 | $canvas ->drawImage( $draw ); |
149 | $canvas ->setImagePage( $width , $height ,0,0); |
152 | $this ->image= $canvas ; |
155 | $size = $this ->image->getImagePage(); |
156 | $src_width = $size [ 'width' ]; |
157 | $src_height = $size [ 'height' ]; |
162 | if ( $src_width * $height > $src_height * $width ){ |
163 | $crop_w = intval ( $src_height * $width / $height ); |
165 | $crop_h = intval ( $src_width * $height / $width ); |
173 | $crop_x = intval (( $src_width - $crop_w )/2); |
177 | $crop_x = $src_width - $crop_w ; |
182 | $crop_y = intval (( $src_height - $crop_h )/2); |
185 | $crop_x = intval (( $src_width - $crop_w )/2); |
186 | $crop_y = intval (( $src_height - $crop_h )/2); |
189 | $crop_x = $src_width - $crop_w ; |
190 | $crop_y = intval (( $src_height - $crop_h )/2); |
194 | $crop_y = $src_height - $crop_h ; |
197 | $crop_x = intval (( $src_width - $crop_w )/2); |
198 | $crop_y = $src_height - $crop_h ; |
201 | $crop_x = $src_width - $crop_w ; |
202 | $crop_y = $src_height - $crop_h ; |
205 | $crop_x = intval (( $src_width - $crop_w )/2); |
206 | $crop_y = intval (( $src_height - $crop_h )/2); |
209 | $canvas = new Imagick(); |
210 | if ( $this ->type== 'gif' ){ |
211 | $images = $image ->coalesceImages(); |
212 | foreach ( $images as $frame ){ |
214 | $img ->readImageBlob( $frame ); |
215 | $img ->cropImage( $crop_w , $crop_h , $crop_x , $crop_y ); |
216 | $img ->thumbnailImage( $width , $height ,true); |
217 | $canvas ->addImage( $img ); |
218 | $canvas ->setImageDelay( $img ->getImageDelay()); |
219 | $canvas ->setImagePage( $width , $height ,0,0); |
222 | $image ->cropImage( $crop_w , $crop_h , $crop_x , $crop_y ); |
223 | $image ->thumbnailImage( $width , $height ,true); |
224 | $canvas ->addImage( $image ); |
225 | $canvas ->setImagePage( $width , $height ,0,0); |
228 | $this ->image= $canvas ; |
237 | public function add_watermark( $path , $x =0, $y =0){ |
238 | $watermark = new Imagick( $path ); |
239 | $draw = new ImagickDraw(); |
240 | $draw ->composite( $watermark ->getImageCompose(), $x , $y , $watermark ->getImageWidth(), $watermark ->getimageheight(), $watermark ); |
241 | if ( $this ->type== 'gif' ){ |
243 | $canvas = new Imagick(); |
244 | $images = $image ->coalesceImages(); |
245 | foreach ( $image as $frame ){ |
247 | $img ->readImageBlob( $frame ); |
248 | $img ->drawImage( $draw ); |
249 | $canvas ->addImage( $img ); |
250 | $canvas ->setImageDelay( $img ->getImageDelay()); |
253 | $this ->image= $canvas ; |
255 | $this ->image->drawImage( $draw ); |
264 | public function add_text( $text , $x =0, $y =0, $angle =0, $style = array ()){ |
265 | $draw = new ImagickDraw(); |
266 | if (isset( $style [ 'font' ])) $draw ->setFont( $style [ 'font' ]); |
267 | if (isset( $style [ 'font_size' ])) $draw ->setFontSize( $style [ 'font_size' ]); |
268 | if (isset( $style [ 'fill_color' ])) $draw ->setFillColor( $style [ 'fill_color' ]); |
269 | if (isset( $style [ 'under_color' ])) $draw ->setTextUnderColor( $style [ 'under_color' ]); |
270 | if ( $this ->type== 'gif' ){ |
271 | foreach ( $this ->image as $frame ){ |
272 | $frame ->annotateImage( $draw , $x , $y , $angle , $text ); |
275 | $this ->image->annotateImage( $draw , $x , $y , $angle , $text ); |
283 | public function save_to( $path ){ |
284 | $this ->image->stripImage(); |
287 | $this ->image->writeImages( $path ,true); |
291 | $this ->image->setImageCompressionQuality( $_ENV [ 'ImgQ' ]); |
292 | $this ->image->writeImage( $path ); |
295 | $flag = $this ->image->getImageAlphaChannel(); |
297 | if (imagick::ALPHACHANNEL_UNDEFINED == $flag or imagick::ALPHACHANNEL_DEACTIVATE == $flag ){ |
298 | $this ->image->setImageType(imagick::IMGTYPE_PALETTE); |
299 | $this ->image->writeImage( $path ); |
301 | $this ->image->writeImage( $path ); |
305 | $this ->image->writeImage( $path ); |
310 | public function output( $header =true){ |
311 | if ( $header ) header( 'Content-type: ' . $this ->type); |
312 | echo $this ->image->getImagesBlob(); |
318 | public function thumbnail( $width =100, $height =100, $fit =true){ $this ->image->thumbnailImage( $width , $height , $fit );} |
325 | public function border( $width , $height , $color = 'rgb(220,220,220)' ){ |
326 | $color = new ImagickPixel(); |
327 | $color ->setColor( $color ); |
328 | $this ->image->borderImage( $color , $width , $height ); |
331 | public function get_width(){ $size = $this ->image->getImagePage(); return $size [ 'width' ];} |
333 | public function get_height(){ $size = $this ->image->getImagePage(); return $size [ 'height' ];} |
335 | public function set_type( $type = 'png' ){ $this ->type= $type ; $this ->image->setImageFormat( $type );} |
337 | public function get_type(){ return $this ->type;} |
338 | public function blur( $radius , $sigma ){ $this ->image->blurImage( $radius , $sigma );} |
339 | public function gaussian_blur( $radius , $sigma ){ $this ->image->gaussianBlurImage( $radius , $sigma );} |
340 | public function motion_blur( $radius , $sigma , $angle ){ $this ->image->motionBlurImage( $radius , $sigma , $angle );} |
341 | public function radial_blur( $radius ){ $this ->image->radialBlurImage( $radius );} |
342 | public function add_noise( $type =null){ $this ->image->addNoiseImage( $type ==null?imagick::NOISE_IMPULSE: $type );} |
343 | public function level( $black_point , $gamma , $white_point ){ $this ->image->levelImage( $black_point , $gamma , $white_point );} |
344 | public function modulate( $brightness , $saturation , $hue ){ $this ->image->modulateImage( $brightness , $saturation , $hue );} |
345 | public function charcoal( $radius , $sigma ){ $this ->image->charcoalImage( $radius , $sigma );} |
346 | public function oil_paint( $radius ){ $this ->image->oilPaintImage( $radius );} |
347 | public function flop(){ $this ->image->flopImage();} |
348 | public function flip(){ $this ->image->flipImage();} |
状况二的解决办法如下:
首先用/usr/local/imagemagick/bin/convert -version指令查看一下输出内容是否已经开啟了多线程,Features:的值为空说明是单线程,如果Features:的值是openMP说明是多线程.imagick的多线程模式有一个bug,他会导致多核心的cpu使用率瞬间飆升到100所以一定要使用它的单线程模式才行.
代码如下:
2 | Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC |
上边是我配置正确时显示的结果,如果没有配置正确会显示下边的结果
代码如下:
2 | Copyright: Copyright (C) 1999-2011 ImageMagick Studio LLC |
第一种结果是单线程模式,第二种结果是多线程模式,因为imagick的多线程模式有bug,所以如果您刚开始是用多线程模式安装的imagick那就必须要yum remove imagemagick将其卸载掉重新安装才行.
经过重写class,重装imagick之后一切正常,而且处理图像的效能比之以前有了大幅提升