20,359
社区成员
发帖
与我相关
我的任务
分享
<?php
/**
* 基于MagickWand的图片缩略图程序, php magick thumb
* Author: smallchicken
* E-mail: microji@163.com
* Version: 1.0
* 用法:直接调用 magick_thumb函数,传入参数:
* magick_thumb($src_image_dir.$src_image,$dst_thumb_dir.$dst_image,100,100,1);
* $src_file : 原文件路径 , $dst_file :保存文件路径 , $dst_width :生成文件宽 , $dst_height:生成文件高,$mode=1 裁剪方式
* GIF动画缩略到不大于传入的高宽值,并且保留动画效果,GIF非动画格式和其他格式一样处理。
* 参数 $mode 说明:
* $mode=1 :生成固定高宽的图像,图片缩放后铺满,为了铺满,会有部分图像裁剪掉。
* $mode=2 :生成固定高宽的图像,图片缩放后不一定铺满,但保留全部图像信息,即不裁剪,添加补白。
* $mode=3 :生成图像高宽不大于给定高宽,并且以缩放后的实际大小保持。
*
*/
function magick_thumb($src_file,$dst_file,$dst_width,$dst_height,$mode=1) {
$mp = new MagickProcess($src_file);
return $mp->MagickThumb($dst_file,$dst_width,$dst_height,$mode);
}
class MagickProcess {
var $src_mw;
var $src_file;
var $src_width;
var $src_height;
var $src_ext;
var $src_format;
var $is_img;
function MagickProcess($src_file) {
$this->src_file = $src_file;
$this->src_mw = NewMagickWand();
$this->is_img=MagickReadImage($this->src_mw,$src_file);
if(!$this->is_img) return;
$this->format = MagickGetImageFormat($this->src_mw);
$this->src_width =MagickGetImageWidth($this->src_mw);
$this->src_height =MagickGetImageHeight($this->src_mw);
}
function IsAnimation() {
$fp=fopen($this->src_file, 'rb');
$image_head = fread($fp,1024);
fclose($fp);
return preg_match("/".chr(0x21).chr(0xff).chr(0x0b).'NETSCAPE2.0'."/",$image_head) ? true : false;
}
function MagickThumb($dst_file,$dst_width,$dst_height,$mode=1) {
if(!$this->is_img) return false;
$src_width = $this->src_width;
$src_height= $this->src_height;
$ratio_w=1.0 * $dst_width / $src_width;
$ratio_h=1.0 * $dst_height / $src_height;
$ratio=1.0;
if(strtolower($this->format)=='gif') {
if ($this->IsAnimation()) {
$this->ResizeGif($dst_file, $dst_width, $dst_height);return;
}
}
switch($mode) {
case 1: // 生成固定高宽,超过的裁剪掉
if($ratio_w < 1 && $ratio_h < 1) { // 都缩小
$ratio = $ratio_w < $ratio_h ? $ratio_h : $ratio_w;
$crop_width = (int)($dst_width / $ratio);
$crop_height = (int)($dst_height / $ratio);
$crop_x = (int) ($src_width-$crop_width)/2 ;
$crop_y = (int) ($src_height-$crop_height)/2 ;
MagickCropImage($this->src_mw, $crop_width, $crop_height, $crop_x, $crop_y);
$this->ResizeImage($this->src_mw, $dst_width, $dst_height);
$this->SaveImage($this->src_mw, $dst_file);
}elseif($ratio_w > 1 && $ratio_h > 1) {
$dst_mkwd=NewMagickWand();
MagickNewImage($dst_mkwd,$dst_width,$dst_height,'#FFFFFF');
$dst_x = (int) abs($dst_width - $src_width) / 2 ;
$dst_y = (int) abs($dst_height -$src_height) / 2;
MagickCompositeImage($dst_mkwd ,$this->src_mw, MW_OverCompositeOp, $dst_x, $dst_y ) ; // 合并图像,拷贝到目标图像的x,y坐标点
$this->SaveImage($dst_mkwd, $dst_file);
DestroyMagickWand($this->src_mw);
}else {
// 一边长,一边短,先裁去长的边。
$crop_x=$crop_y=0;
$crop_width = min($src_width , $dst_width);
$crop_height = min($src_height, $dst_height);
$crop_x = (int) ($src_width-$crop_width)/2 ;
$crop_y = (int) ($src_height-$crop_height)/2 ;
MagickCropImage($this->src_mw, $crop_width, $crop_height, $crop_x, $crop_y);
$dst_mkwd=NewMagickWand();
MagickNewImage($dst_mkwd,$dst_width,$dst_height,'#FFFFFF');
$dst_x = (int) ($dst_width-$crop_width)/2 ;
$dst_y = (int) ($dst_height-$crop_height)/2 ;
MagickCompositeImage($dst_mkwd ,$this->src_mw, MW_OverCompositeOp, $dst_x, $dst_y ) ; // 合并图像,拷贝到目标图像的x,y坐标点
$this->SaveImage($dst_mkwd, $dst_file);
DestroyMagickWand($this->src_mw);
}
break;
case 2: // 生成固定高宽,保留全部信息,只缩放,不裁剪
if($ratio_w > 1 && $ratio_h > 1) {
$dst_mkwd=NewMagickWand();
MagickNewImage($dst_mkwd,$dst_width,$dst_height,'#FFFFFF');
$dst_x = (int) abs($dst_width - $src_width) / 2 ;
$dst_y = (int) abs($dst_height -$src_height) / 2;
MagickCompositeImage($dst_mkwd ,$this->src_mw, MW_OverCompositeOp, $dst_x, $dst_y ) ;
$this->SaveImage($dst_mkwd, $dst_file);
DestroyMagickWand($this->src_mw);
}else {
$ratio = $ratio_w > $ratio_h ? $ratio_h : $ratio_w;
$tmp_w = (int)($src_width * $ratio);
$tmp_h = (int)($src_height * $ratio);
$this->ResizeImage($this->src_mw, $tmp_w, $tmp_h);
$dst_mkwd=NewMagickWand();
MagickNewImage($dst_mkwd,$dst_width,$dst_height,'#FFFFFF');
$dst_x = (int) abs($tmp_w - $dst_width) / 2 ;
$dst_y = (int) abs($tmp_h - $dst_height) / 2;
MagickCompositeImage($dst_mkwd ,$this->src_mw, MW_OverCompositeOp, $dst_x, $dst_y ) ;
$this->SaveImage($dst_mkwd, $dst_file);
DestroyMagickWand($this->src_mw);
}
break;
case 3: // 超过缩放,不超过直接存图。
if($ratio_w > 1 && $ratio_h > 1) {
$this->SaveImage($this->src_mw, $dst_file);
}else {
$ratio = $ratio_w > $ratio_h ? $ratio_h : $ratio_w;
$tmp_w = (int)($src_width * $ratio);
$tmp_h = (int)($src_height * $ratio);
$this->ResizeImage($this->src_mw, $tmp_w, $tmp_h);
$this->SaveImage($this->src_mw, $dst_file);
}
break;
}
return true;
}
function ResizeGif($dst_file,$dst_width, $dst_height) {
MagickResetIterator($this->src_mw);
do {
$iw = MagickGetImageWidth($this->src_mw);
$ih = MagickGetImageHeight($this->src_mw);
$iratio=1.0;
$iratio_w = doubleval($iw) / doubleval($dst_width);
$iratio_h = doubleval($ih) / doubleval($dst_height);
$iratio = $iratio_w > $iratio_h ? $iratio_w : $iratio_h;
$tmp_w = floor( $iw / $iratio);
$tmp_h = floor( $ih / $iratio);
$this->ResizeImage($this->src_mw, $tmp_w, $tmp_h);
} while(MagickNextImage($this->src_mw));
$this->SaveImage($this->src_mw, $dst_file);
}
function ResizeImage($mgk, $dst_width, $dst_height) {
MagickResizeImage( $mgk, $dst_width, $dst_height, MW_LanczosFilter, 1.0);
//MagickSampleImage($mw, $dst_width, $dst_height); // Resize的效果好于Sample
//MagickScaleImage($mw, $dst_width, $dst_height);
/*
*
MW_PointFilter MW_BoxFilter
MW_TriangleFilter MW_HermiteFilter
MW_HanningFilter MW_HammingFilter
MW_BlackmanFilter MW_GaussianFilter
MW_QuadraticFilter MW_CubicFilter
MW_CatromFilter MW_MitchellFilter
MW_LanczosFilter MW_BesselFilter
MW_SincFilter
*/
}
function SaveImage($mgk,$dst_file) {
MagickSetFormat($mgk, $this->format);
MagickWriteImages($mgk, $dst_file, MagickTrue);
DestroyMagickWand($mgk);
unset($mgk);
}
}// end class
?>