imgareaselect+php实现图片裁剪保存

目标:在用户上传头像文件时,对原文件进行固定比例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                             width: '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                         width: '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                             width: 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                             width: 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 }

 效果图

posted on 2013-01-13 17:04  jenqz  阅读(695)  评论(0编辑  收藏  举报