目标:在用户上传头像文件时,对原文件进行固定比例3:2裁剪,同时生成1:1的不同尺寸的头像文件。另外还要在页面上预览。
主页html, index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <link href="css/imgareaselect-default.css" rel="stylesheet" type="text/css" /> <style> #facediv {display:none;z-index:100;} .img_style{float:left; position: relative; overflow: hidden;} .img_thumb{width:270px; height:180px;} .img_max{width:100px; height:100px;} .img_mid{width:50px; height:50px;} </style> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/ajaxfileupload.js"></script> <script type="text/javascript" src="js/jquery.imgareaselect.pack.js"></script> <script type="text/javascript" src="js/upload.js"></script> </head> <body> <input type="hidden" name="x1" value="0" /> <input type="hidden" name="y1" value="0" /> <input type="hidden" name="x2" value="100" /> <input type="hidden" name="y2" value="100" /> <input id="fileToUpload" name="fileToUpload" type="file" onchange="uploadImage();"/> <div id="facediv"> <img id="face" class="img_style"/> </div> </body> </html>
js文件,upload.js
upload.js
1 function uploadImage() { 2 //上传 3 $.ajaxFileUpload( { 4 url : 'photo.php?act=upload', 5 fileElementId : 'fileToUpload', 6 dataType : 'json',// 服务器返回的格式,php端用了header ( 'Content-type: application/json' ); 反而提示格式不对。 7 success : function(data) { 8 if (data['result'] == 1) { 9 $("#facediv").css({"display":"block"}); 10 $("#face").attr("src",data['path']); 11 12 //先清理旧内容 13 if($("#preview_3x2").length>0){ 14 $("#preview_3x2 img").attr("src", data['path']); 15 $("#preview_1x1 img").attr("src", data['path']); 16 17 $("#btnSubmit").click(function (){ 18 cutImage(data['path']); 19 }) 20 }else{ 21 $('<div id="preview_3x2"><img src="' + data['path'] + '" style="position: relative;" /><div>') 22 .css({ 23 float: 'left', 24 position: 'relative', 25 overflow: 'hidden', 26 '270px', 27 height: '180px' 28 }).insertAfter($('#face')); 29 $('<div id="preview_1x1"><img src="' + data['path'] + '" style="position: relative;" /><div>') 30 .css({ 31 float: 'left', 32 position: 'relative', 33 overflow: 'hidden', 34 '100px', 35 height: '100px' 36 }).insertAfter($('#face')); 37 38 $('<button id="btnSubmit">提交</button>') 39 .click(function (){ 40 cutImage(data['path']); 41 }).insertAfter($('#facediv')); 42 } 43 44 $('#face').imgAreaSelect({ 45 //maxWidth: 1200, maxHeight: 800, 46 minWidth: 270, minHeight: 180, 47 //x1:0,y1:0,x2:180,y2:120, 48 aspectRatio: '3:2', 49 onSelectChange: function (img, selection) { 50 var scaleX = 270 / (selection.width || 1); 51 var scaleY = 180 / (selection.height || 1); 52 53 var offset_x = Math.round((selection.width-selection.height)/2); 54 55 var scaleY_cube = 100 / (selection.height || 1); 56 var scaleX_cube = scaleY_cube; 57 58 $('#preview_3x2 > img').css({ 59 Math.round(scaleX * img.width) + 'px', 60 height: Math.round(scaleY * img.height) + 'px', 61 marginLeft: '-' + Math.round(scaleX * selection.x1) + 'px', 62 marginTop: '-' + Math.round(scaleY * selection.y1) + 'px' 63 }); 64 65 $('#preview_1x1 > img').css({ 66 Math.round(scaleX_cube * img.width) + 'px', 67 height: Math.round(scaleY_cube * img.height) + 'px', 68 marginLeft: '-' + Math.round(scaleX * (selection.x1)) + 'px', 69 marginTop: '-' + Math.round(scaleY * selection.y1) + 'px' 70 }); 71 }, 72 onSelectEnd: function (img, selection) { 73 $('input[name="x1"]').val(selection.x1); 74 $('input[name="y1"]').val(selection.y1); 75 $('input[name="x2"]').val(selection.x2); 76 $('input[name="y2"]').val(selection.y2); 77 } 78 }); 79 } 80 }, 81 error : function(data) { 82 //alert("upload fail!"); 83 } 84 }); 85 } 86 87 function cutImage(path) { 88 $.ajax( { 89 type : "POST", 90 url:"photo.php?act=save", 91 dateType:"json", 92 data:{ 93 "x1":$('input[name="x1"]').val(), 94 "x2":$('input[name="x2"]').val(), 95 "y1":$('input[name="y1"]').val(), 96 "y2":$('input[name="y2"]').val(), 97 "path":path 98 }, 99 success : function(data) { 100 alert("保存成功!"); 101 }, 102 error:function(data) { 103 alert("保存失败!原因:"+data['errors']); 104 } 105 }); 106 }
下面是服务器端的php处理文件,根据提交的action作相应的动作,具体步骤如下:
1.首先是把图片上传到服务器保存,然后存储路径转化为url(path)传给客户端;
2.客户端接收消息后判断如果正确保存,则动态创建裁剪预览效果,同时预览3:2和1:1两种效果,默认为3:2,1:2的效果根据3:2的做相应处理;
3.用户选定效果后,隐式提交起始点(x1,y1)和终结点(x2,y2)的坐标;
4.php程序再根据坐标值运用imagic或gd的输出函数生成相应大小的缩略图;
photo.php
1 <?php 2 class photo { 3 private $base_path = '/'; 4 private $upload_path = 'upload'; 5 6 function __construct() { 7 $this->base_path = dirname ( __FILE__ ); 8 $this->upload_path = $this->base_path . '/upload/'; 9 } 10 11 public function upload() { 12 $rets ['result'] = 0; 13 if (in_array ( $_FILES ["fileToUpload"] ["type"], array ("image/gif", "image/jpeg", "image/pjpeg" ) )) { 14 if ($_FILES ["fileToUpload"] ["size"] < 6000000) { 15 if ($_FILES ["fileToUpload"] ["error"] > 0) { 16 $rets ['debug'] = 'image type is invalid!'; 17 } else { 18 $debug = "upload - " . $_FILES ["fileToUpload"] ["name"]; 19 $debug .= "type - " . $_FILES ["fileToUpload"] ["type"]; 20 $debug .= "size - " . ($_FILES ["fileToUpload"] ["size"] / 1024) . " kb"; 21 $debug .= "temp file - " . $_FILES ["fileToUpload"] ["tmp_name"]; 22 23 $src_img_file = $this->upload_path . $_FILES ["fileToUpload"] ["name"]; 24 $dest_img_file = dirname ( $src_img_file ) . '/max_' . $_FILES ["fileToUpload"] ["name"]; 25 26 if (file_exists ( $src_img_file )) { 27 unlink ( $src_img_file ); 28 } 29 if (file_exists ( $dest_img_file )) { 30 unlink ( $dest_img_file ); 31 } 32 33 move_uploaded_file ( $_FILES ["fileToUpload"] ["tmp_name"], $src_img_file ); 34 35 //先将原图等比例生成前台能显示的最大尺寸(这地方是否可以让用户选:1-是等比例缩放后截取,2-是原尺寸截取?) 36 /* include_once 'image.php'; 37 $image = new core_image(); 38 39 $config = array( 40 'quality' => 90, 41 'source_image' => $src_img_file, 42 'new_image' => $dest_img_file, 43 'width'=>360, 44 'height'=>240 45 ); 46 47 $image->initialize($config)->Resize(); 48 unlink($src_img_file);*/ 49 50 $rets ['result'] = 1; 51 $rets ['path'] = 'http://localhost/test/image/cut_image/upload/' . $_FILES ["fileToUpload"] ["name"]; 52 //$rets ['path'] = 'http://localhost/test/image/cut_image/upload/max_' . $_FILES ["fileToUpload"] ["name"]; 53 $rets ['debug'] = $debug; 54 55 } 56 } else { 57 $rets ['debug'] = "file size is too large."; 58 } 59 } else { 60 $rets ['debug'] = "invalid file type"; 61 } 62 63 //header ( 'Content-type: application/json' ); 64 echo json_encode ( $rets ); 65 } 66 67 public function save($rect, $path) { 68 $rets ['result'] = 0; 69 $file_parts = explode ( '/upload/', $path ); 70 if (count ( $file_parts ) > 1) { 71 //$file_parts = explode('/', $string) 72 $pos = strrpos ( $file_parts [1], '.' ); 73 $filename = substr ( $file_parts [1], 0, $pos ); 74 $ext = substr ( $file_parts [1], $pos ); 75 $source_path = $this->upload_path . $file_parts [1]; 76 77 $target_path = $this->upload_path . $filename . '_thumb' . $ext; 78 $target_path_mid = $this->upload_path . $filename . '_mid' . $ext; 79 $target_path_max = $this->upload_path . $filename . '_max' . $ext; 80 81 $this->cut_image ( $source_path, $target_path, $rect, 270, 180 ); 82 $this->cut_image ( $source_path, $target_path_mid, $rect, 50, 50 ); 83 $this->cut_image ( $source_path, $target_path_max, $rect, 100, 100 ); 84 85 $rets ['result'] = 1; 86 $rets ['path'] = 'http://localhost/test/image/cut_image/upload/' . $filename . '_thumb' . $ext; 87 $rets ['debug'] = implode ( ',', $rect ); 88 unlink ( $source_path ); 89 90 } 91 92 //header ( 'Content-type: application/json' ); 93 echo json_encode ( $rets ); 94 } 95 96 private function cut_image($source_path, $target_path, $rect, $width, $height) { 97 include_once 'image.php'; 98 99 $image = new core_image (); 100 $image->initialize ( array ( 101 'quality' => 90, 102 'source_image' => $source_path, 103 'new_image' => $target_path, 104 'start_x' => $rect ['x1'], 105 'start_y' => $rect ['y1'], 106 'end_x' => $rect ['x2'], 107 'end_y' => $rect ['y2'], 108 'width' => $width, 109 'height' => $height ) 110 )->resize (); 111 112 } 113 114 public function test() { 115 $rect = array ('x1' => 100, 'y1' => 87, 'x2' => 575, 'y2' => 562 ); //299 , 87 , 774, 562 116 include_once 'image.php'; 117 $image = new core_image (); 118 $image->initialize ( array ('quality' => 90, 119 'source_image' => "E:/projects/php/test/image/cut_image/upload/Hydrangeas.jpg", 120 'new_image' => "E:/projects/php/test/image/cut_image/upload/Hydrangeas_thumb.jpg", 121 'start_x' => $rect ['x1'], 122 'start_y' => $rect ['y1'], 123 'end_x' => $rect ['x2'], 124 'end_y' => $rect ['y2'], 125 'width' => 400, 126 'height' => 400 ) 127 )->resize (); 128 } 129 } 130 131 $act = isset ( $_GET ['act'] ) ? $_GET ['act'] : ''; 132 133 if (! empty ( $act )) { 134 $photo = new photo (); 135 if ($act == 'upload') { 136 $photo->upload (); 137 } elseif ($act == "save") { 138 $x1 = $_POST ["x1"]; 139 $y1 = $_POST ["y1"]; 140 $x2 = $_POST ["x2"]; 141 $y2 = $_POST ["y2"]; 142 $path = $_POST ["path"]; 143 $rect = array ('x1' => $x1, 'y1' => $y1, 'x2' => $x2, 'y2' => $y2 ); 144 $photo->save ( $rect, $path ); 145 } elseif ($act == 'test') { 146 $photo->test (); 147 } 148 }
另外是一个图片处理类,image.php。我在里面改了一个方法imageProcessGDByRect用户根据两个坐标点来计算宽和高。
image.php
1 <?php 2 define ( "IMAGE_CORE_OP_TO_FILE", 1 ); // Output to file 3 define ( "IMAGE_CORE_OP_OUTPUT", 2 ); // Output to browser 4 5 6 define ( "IMAGE_CORE_SC_NOT_KEEP_SCALE", 4 ); // Free scale 7 define ( "IMAGE_CORE_SC_BEST_RESIZE_WIDTH", 8 ); // Scale to width 8 define ( "IMAGE_CORE_SC_BEST_RESIZE_HEIGHT", 16 ); // Scale to height 9 10 11 define ( "IMAGE_CORE_CM_DEFAULT", 0 ); // Clipping method: default 12 define ( "IMAGE_CORE_CM_LEFT_OR_TOP", 1 ); // Clipping method: left or top 13 define ( "IMAGE_CORE_CM_MIDDLE", 2 ); // Clipping method: middle 14 define ( "IMAGE_CORE_CM_RIGHT_OR_BOTTOM", 3 ); // Clipping method: right or bottom 15 16 17 class core_image { 18 var $image_library = 'gd'; 19 20 var $source_image; 21 var $new_image; 22 var $width; 23 var $height; 24 var $quality = 90; 25 26 var $option = IMAGE_CORE_OP_TO_FILE; 27 28 var $scale; 29 30 // clipping method 0: default 1: left or top 2: middle 3: right or bottom 31 var $clipping = IMAGE_CORE_CM_MIDDLE; //IMAGE_CORE_CM_MIDDLE; 32 33 34 var $start_x = 0; // start X axis (pixel) 35 var $start_y = 0; // start Y axis (pixel) 36 var $end_x = 0; // end X axis (pixel) 37 var $end_y = 0; // end Y axis (pixel) 38 39 40 private $image_type = array (1 => 'gif', 2 => 'jpeg', 3 => 'png' ); 41 42 private $image_type_index = array ('gif' => 1, 'jpg' => 2, 'jpeg' => 2, 'jpe' => 2, 'png' => 3 ); 43 44 private $image_info; 45 private $image_ext; 46 47 public function initialize($config = array()) { 48 if (class_exists ( 'Imagick', false )) { 49 $this->image_library = 'imagemagick'; 50 } 51 52 if (sizeof ( $config ) > 0) { 53 foreach ( $config as $key => $value ) { 54 $this->$key = $value; 55 } 56 } 57 58 return $this; 59 } 60 61 public function Resize() { 62 if (! file_exists ( $this->source_image )) { 63 $this->show_error ( 'Core_Image: Source file not exists: ' . $this->source_image ); 64 } 65 66 $this->image_info = @getimagesize ( $this->source_image ); 67 68 switch ($this->image_info [2]) { 69 default : 70 $this->show_error ( 'Core_Image: Can\'t detect output image\'s type.' ); 71 break; 72 73 case 1 : 74 $this->image_ext = 'gif'; 75 break; 76 77 case 2 : 78 $this->image_ext = 'jpg'; 79 break; 80 81 case 3 : 82 $this->image_ext = 'png'; 83 break; 84 } 85 86 if ($this->image_library == 'imagemagick') { 87 return $this->imageProcessImageMagick (); 88 } else { 89 //return $this->imageProcessGD (); 90 if(empty($this->end_x)||empty($this->end_y)){ 91 return $this->imageProcessGD(); 92 }else{ 93 return $this->imageProcessGDByRect(); 94 } 95 } 96 } 97 98 private function imageProcessImageMagick() { 99 $this->source_image_w = $this->image_info [0]; 100 $this->source_image_h = $this->image_info [1]; 101 102 $this->source_image_x = 0; 103 $this->source_image_y = 0; 104 105 $dst_x = 0; 106 $dst_y = 0; 107 108 if ($this->clipping != IMAGE_CORE_CM_DEFAULT) { 109 // clipping method 1: left or top 2: middle 3: right or bottom 110 111 112 $this->source_image_w -= $this->start_x; 113 $this->source_image_h -= $this->start_y; 114 115 if ($this->source_image_w * $this->height > $this->source_image_h * $this->width) { 116 $match_w = round ( $this->width * $this->source_image_h / $this->height ); 117 $match_h = $this->source_image_h; 118 } else { 119 $match_h = round ( $this->height * $this->source_image_w / $this->width ); 120 $match_w = $this->source_image_w; 121 } 122 123 switch ($this->clipping) { 124 case IMAGE_CORE_CM_LEFT_OR_TOP : 125 $this->source_image_x = 0; 126 $this->source_image_y = 0; 127 break; 128 129 case IMAGE_CORE_CM_MIDDLE : 130 $this->source_image_x = round ( ($this->source_image_w - $match_w) / 2 ); 131 $this->source_image_y = round ( ($this->source_image_h - $match_h) / 2 ); 132 break; 133 134 case IMAGE_CORE_CM_RIGHT_OR_BOTTOM : 135 $this->source_image_x = $this->source_image_w - $match_w; 136 $this->source_image_y = $this->source_image_h - $match_h; 137 break; 138 } 139 140 $this->source_image_w = $match_w; 141 $this->source_image_h = $match_h; 142 $this->source_image_x += $this->start_x; 143 $this->source_image_y += $this->start_y; 144 } 145 146 $resize_height = $this->height; 147 $resize_width = $this->width; 148 149 if ($this->scale != IMAGE_CORE_SC_NOT_KEEP_SCALE) { 150 if ($this->scale == IMAGE_CORE_SC_BEST_RESIZE_WIDTH) { 151 $resize_height = round ( $this->width * $this->source_image_h / $this->source_image_w ); 152 $resize_width = $this->width; 153 } else if ($this->scale == IMAGE_CORE_SC_BEST_RESIZE_HEIGHT) { 154 $resize_width = round ( $this->height * $this->source_image_w / $this->source_image_h ); 155 $resize_height = $this->height; 156 } 157 } 158 159 $im = new Imagick (); 160 161 $im->readimageblob ( file_get_contents ( $this->source_image ) ); 162 163 $im->setCompressionQuality ( $this->quality ); 164 165 if ($this->source_image_x or $this->source_image_y) { 166 $im->cropImage ( $this->source_image_w, $this->source_image_h, $this->source_image_x, $this->source_image_y ); 167 } 168 169 $im->thumbnailImage ( $resize_width, $resize_height, true ); 170 171 if ($this->option == IMAGE_CORE_OP_TO_FILE and $this->new_image) { 172 file_put_contents ( $this->new_image, $im->getimageblob () ); 173 } else if ($this->option == IMAGE_CORE_OP_OUTPUT) { 174 $output = $im->getimageblob (); 175 $outputtype = $im->getFormat (); 176 177 header ( "Content-type: $outputtype" ); 178 echo $output; 179 die (); 180 } 181 182 return TRUE; 183 } 184 185 private function imageProcessGD() { 186 $func_output = 'image' . $this->image_type [$this->image_type_index [$this->image_ext]]; 187 //判断图片输出函数是否存在 188 if (! function_exists ( $func_output )) { 189 $this->show_error ( 'Core_Image: Function not exists for output: ' . $func_output ); 190 } 191 192 $func_create = 'imagecreatefrom' . $this->image_type [$this->image_info [2]]; //list($width, $height, $type, $attr) = getimagesize("img/flag.jpg"); 193 //判断创建此类型图片的函数是否存在 194 if (! function_exists ( $func_create )) { 195 $this->show_error ( 'Core_Image: Function not exists for output: ' . $func_create ); 196 } 197 198 $im = $func_create ( $this->source_image ); //导入原图 199 //获取原图宽和高 200 $this->source_image_w = $this->image_info [0]; 201 $this->source_image_h = $this->image_info [1]; 202 203 $this->source_image_x = 0; 204 $this->source_image_y = 0; 205 206 $dst_x = 0; 207 $dst_y = 0; 208 209 if ($this->scale == IMAGE_CORE_SC_BEST_RESIZE_WIDTH) { 210 $this->height = round ( $this->width * $this->source_image_h / $this->source_image_w ); 211 } 212 213 if ($this->scale & IMAGE_CORE_SC_BEST_RESIZE_HEIGHT) { 214 $this->width = round ( $this->height * $this->source_image_w / $this->source_image_h ); 215 } 216 217 $fdst_w = $this->width; 218 $fdst_h = $this->height; 219 220 if ($this->clipping != IMAGE_CORE_CM_DEFAULT) { 221 // clipping method 1: left or top 2: middle 3: right or bottom 222 223 224 $this->source_image_w -= $this->start_x; 225 $this->source_image_h -= $this->start_y; 226 227 if ($this->source_image_w * $this->height > $this->source_image_h * $this->width) { 228 $match_w = round ( $this->width * $this->source_image_h / $this->height ); 229 $match_h = $this->source_image_h; 230 } else { 231 $match_h = round ( $this->height * $this->source_image_w / $this->width ); 232 $match_w = $this->source_image_w; 233 } 234 235 switch ($this->clipping) { 236 case IMAGE_CORE_CM_LEFT_OR_TOP : 237 $this->source_image_x = 0; 238 $this->source_image_y = 0; 239 break; 240 241 case IMAGE_CORE_CM_MIDDLE : 242 $this->source_image_x = round ( ($this->source_image_w - $match_w) / 2 ); 243 $this->source_image_y = round ( ($this->source_image_h - $match_h) / 2 ); 244 break; 245 246 case IMAGE_CORE_CM_RIGHT_OR_BOTTOM : 247 $this->source_image_x = $this->source_image_w - $match_w; 248 $this->source_image_y = $this->source_image_h - $match_h; 249 break; 250 } 251 252 $this->source_image_w = $match_w; 253 $this->source_image_h = $match_h; 254 $this->source_image_x += $this->start_x; 255 $this->source_image_y += $this->start_y; 256 257 } else if ($this->scale != IMAGE_CORE_SC_NOT_KEEP_SCALE) { 258 if ($this->source_image_w * $this->height > $this->source_image_h * $this->width) { 259 $fdst_h = round ( $this->source_image_h * $this->width / $this->source_image_w ); 260 $dst_y = floor ( ($this->height - $fdst_h) / 2 ); 261 $fdst_w = $this->width; 262 } else { 263 $fdst_w = round ( $this->source_image_w * $this->height / $this->source_image_h ); 264 $dst_x = floor ( ($this->width - $fdst_w) / 2 ); 265 $fdst_h = $this->height; 266 } 267 268 if ($dst_x < 0) { 269 $dst_x = 0; 270 $dst_y = 0; 271 } 272 273 if ($dst_x > ($this->width / 2)) { 274 $dst_x = floor ( $this->width / 2 ); 275 } 276 277 if ($dst_y > ($this->height / 2)) { 278 $dst_y = floor ( $this->height / 2 ); 279 } 280 } 281 282 if (function_exists ( 'imagecopyresampled' ) and function_exists ( 'imagecreatetruecolor' )) // GD Version Check 283 { 284 $func_create = 'imagecreatetruecolor'; 285 $func_resize = 'imagecopyresampled'; 286 } else { 287 $func_create = 'imagecreate'; 288 $func_resize = 'imagecopyresized'; 289 } 290 291 $dst_img = $func_create ( $this->width, $this->height ); 292 293 if ($this->image_ext == 'png') // png we can actually preserve transparency 294 { 295 imagealphablending ( $dst_img, FALSE ); 296 imagesavealpha ( $dst_img, TRUE ); 297 } 298 299 $func_resize ( $dst_img, $im, $dst_x, $dst_y, $this->source_image_x, $this->source_image_y, $fdst_w, $fdst_h, $this->source_image_w, $this->source_image_h ); 300 301 if ($this->option == IMAGE_CORE_OP_TO_FILE and $this->new_image) { 302 if (file_exists ( $this->new_image )) { 303 @unlink ( $this->new_image ); 304 } 305 306 switch ($this->image_type_index [$this->image_ext]) { 307 case 1 : 308 case 3 : 309 $func_output ( $dst_img, $this->new_image ); 310 break; 311 312 case 2 : // JPEG 313 $func_output ( $dst_img, $this->new_image, $this->quality ); 314 break; 315 } 316 } else if ($this->option == IMAGE_CORE_OP_OUTPUT) { 317 if (function_exists ( "headers_sent" ) and headers_sent ()) { 318 $this->show_error ( 'Core_Image: HTTP already sent, can\'t output image to browser.' ); 319 } 320 321 header ( 'Content-Type: image/' . $this->image_type [$this->image_type_index [$this->image_ext]] ); 322 323 switch ($this->image_type_index [$this->image_ext]) { 324 case 1 : 325 case 3 : 326 $func_output ( $dst_img ); 327 break; 328 329 case 2 : // JPEG 330 $func_output ( $dst_img, '', $this->quality ); 331 break; 332 } 333 334 die (); 335 } 336 337 @imagedestroy ( $im ); 338 @imagedestroy ( $dst_img ); 339 340 return TRUE; 341 } 342 343 private function imageProcessGDByRect() { 344 $func_output = 'image' . $this->image_type [$this->image_type_index [$this->image_ext]]; 345 //判断图片输出函数是否存在 346 if (! function_exists ( $func_output )) { 347 $this->show_error ( 'Core_Image: Function not exists for output: ' . $func_output ); 348 } 349 350 $func_create = 'imagecreatefrom' . $this->image_type [$this->image_info [2]]; //list($width, $height, $type, $attr) = getimagesize("img/flag.jpg"); 351 //判断创建此类型图片的函数是否存在 352 if (! function_exists ( $func_create )) { 353 $this->show_error ( 'Core_Image: Function not exists for output: ' . $func_create ); 354 } 355 356 $im = $func_create ( $this->source_image ); //导入原图 357 //获取原图宽和高 358 $this->source_image_w = $this->image_info [0]; 359 $this->source_image_h = $this->image_info [1]; 360 361 $this->source_image_x = 0; 362 $this->source_image_y = 0; 363 364 $dst_x = 0; 365 $dst_y = 0; 366 367 if ($this->scale == IMAGE_CORE_SC_BEST_RESIZE_WIDTH) { 368 $this->height = round ( $this->width * $this->source_image_h / $this->source_image_w ); 369 } 370 371 if ($this->scale & IMAGE_CORE_SC_BEST_RESIZE_HEIGHT) { 372 $this->width = round ( $this->height * $this->source_image_w / $this->source_image_h ); 373 } 374 375 $fdst_w = $this->width; 376 $fdst_h = $this->height; 377 378 if ($this->clipping != IMAGE_CORE_CM_DEFAULT) { 379 // clipping method 1: left or top 2: middle 3: right or bottom 380 381 382 //按起始坐标和终止坐标计算宽高 383 if($this->end_x > $this->start_x && $this->end_y > $this->start_y){ 384 $this->source_image_w = $this->end_x - $this->start_x; 385 $this->source_image_h = $this->end_y - $this->start_y; 386 }else{ 387 $this->source_image_w -= $this->start_x; 388 $this->source_image_h -= $this->start_y; 389 } 390 //如果目标是正方形,则将长方形截成正方形 391 if($this->source_image_w!=$this->source_image_h && $this->width==$this->height){ 392 if($this->source_image_w>$this->source_image_h){ 393 $w_offset = round(($this->source_image_w - $this->source_image_h)/2); 394 $this->start_x += $w_offset; 395 $this->source_image_w = $this->source_image_h; 396 }else{ 397 $h_offset = round(($this->source_image_h - $this->source_image_w)/2); 398 $this->start_y += $h_offset; 399 $this->source_image_h = $this->source_image_w; 400 } 401 } 402 403 /* if ($this->source_image_w * $this->height > $this->source_image_h * $this->width) { 404 $match_w = round ( $this->width * $this->source_image_h / $this->height ); 405 $match_h = $this->source_image_h; 406 } else { 407 $match_h = round ( $this->height * $this->source_image_w / $this->width ); 408 $match_w = $this->source_image_w; 409 } 410 411 switch ($this->clipping) { 412 case IMAGE_CORE_CM_LEFT_OR_TOP : 413 $this->source_image_x = 0; 414 $this->source_image_y = 0; 415 break; 416 417 case IMAGE_CORE_CM_MIDDLE : 418 $this->source_image_x = round ( ($this->source_image_w - $match_w) / 2 ); 419 $this->source_image_y = round ( ($this->source_image_h - $match_h) / 2 ); 420 break; 421 422 case IMAGE_CORE_CM_RIGHT_OR_BOTTOM : 423 $this->source_image_x = $this->source_image_w - $match_w; 424 $this->source_image_y = $this->source_image_h - $match_h; 425 break; 426 } 427 428 $this->source_image_w = $match_w; 429 $this->source_image_h = $match_h;*/ 430 $this->source_image_x += $this->start_x; 431 $this->source_image_y += $this->start_y; 432 433 } else if ($this->scale != IMAGE_CORE_SC_NOT_KEEP_SCALE) { 434 if ($this->source_image_w * $this->height > $this->source_image_h * $this->width) { 435 $fdst_h = round ( $this->source_image_h * $this->width / $this->source_image_w ); 436 $dst_y = floor ( ($this->height - $fdst_h) / 2 ); 437 $fdst_w = $this->width; 438 } else { 439 $fdst_w = round ( $this->source_image_w * $this->height / $this->source_image_h ); 440 $dst_x = floor ( ($this->width - $fdst_w) / 2 ); 441 $fdst_h = $this->height; 442 } 443 444 if ($dst_x < 0) { 445 $dst_x = 0; 446 $dst_y = 0; 447 } 448 449 if ($dst_x > ($this->width / 2)) { 450 $dst_x = floor ( $this->width / 2 ); 451 } 452 453 if ($dst_y > ($this->height / 2)) { 454 $dst_y = floor ( $this->height / 2 ); 455 } 456 } 457 458 if (function_exists ( 'imagecopyresampled' ) and function_exists ( 'imagecreatetruecolor' )) // GD Version Check 459 { 460 $func_create = 'imagecreatetruecolor'; 461 $func_resize = 'imagecopyresampled'; 462 } else { 463 $func_create = 'imagecreate'; 464 $func_resize = 'imagecopyresized'; 465 } 466 467 $dst_img = $func_create ( $this->width, $this->height ); 468 469 if ($this->image_ext == 'png') // png we can actually preserve transparency 470 { 471 imagealphablending ( $dst_img, FALSE ); 472 imagesavealpha ( $dst_img, TRUE ); 473 } 474 // echo "dst_x={$dst_x};dst_y=$dst_y; 475 // source_image_x={$this->source_image_x};source_image_y={$this->source_image_y}; 476 // fdst_w = {$fdst_w};fdst_h={$fdst_h}; 477 // source_image_w={$this->source_image_w};source_image_h={$this->source_image_h}"; 478 // die(); 479 $func_resize ( $dst_img, $im, $dst_x, $dst_y, $this->source_image_x, $this->source_image_y, $fdst_w, $fdst_h, $this->source_image_w, $this->source_image_h ); 480 481 if ($this->option == IMAGE_CORE_OP_TO_FILE and $this->new_image) { 482 if (file_exists ( $this->new_image )) { 483 @unlink ( $this->new_image ); 484 } 485 486 switch ($this->image_type_index [$this->image_ext]) { 487 case 1 : 488 case 3 : 489 $func_output ( $dst_img, $this->new_image ); 490 break; 491 492 case 2 : // JPEG 493 $func_output ( $dst_img, $this->new_image, $this->quality ); 494 break; 495 } 496 } else if ($this->option == IMAGE_CORE_OP_OUTPUT) { 497 if (function_exists ( "headers_sent" ) and headers_sent ()) { 498 $this->show_error ( 'Core_Image: HTTP already sent, can\'t output image to browser.' ); 499 } 500 501 header ( 'Content-Type: image/' . $this->image_type [$this->image_type_index [$this->image_ext]] ); 502 503 switch ($this->image_type_index [$this->image_ext]) { 504 case 1 : 505 case 3 : 506 $func_output ( $dst_img ); 507 break; 508 509 case 2 : // JPEG 510 $func_output ( $dst_img, '', $this->quality ); 511 break; 512 } 513 514 die (); 515 } 516 517 @imagedestroy ( $im ); 518 @imagedestroy ( $dst_img ); 519 520 return TRUE; 521 } 522 523 function show_error($errorMessage = '') { 524 echo "core_image error - $errorMessage"; 525 exit (); 526 } 527 }
效果图