Created
April 11, 2013 06:25
-
-
Save msurguy/5361174 to your computer and use it in GitHub Desktop.
Blueimp image upload + cropping on the server as described in https://github.com/blueimp/jQuery-File-Upload/issues/1314
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Hi. To integrate jcrop i used a done callback. This means i add jcrop only after successful upload. In general its look like this: on done you have data object. Data.result is an array of files' information returned from server. For each file (image) you need to create separate cropbox, and initialize jcrop plugin for each cropbox after image was loaded. Than post that data to server and handle croping of image on server side. Well, it's my solution, but there are many another ways. | |
| Code: | |
| var cropbox_indx = 0, //index of cropbox | |
| img_data = {}, // keeps uploaded image data | |
| crop_w = 150, | |
| crop_h = 125; | |
| $('#fileupload').fileupload({ | |
| done: function (e, data) { | |
| cropbox_indx += 1; | |
| $.each(data.result, function (index, file) { | |
| if (data.error == undefined && file.error == undefined){ | |
| // show uploaded images and initialize cropbox | |
| var id_upload = 'upload'+cropbox_indx, | |
| id_img = 'cropbox'+cropbox_indx, | |
| img_container = $('<div/>').attr({'id': id_upload, 'class': 'image'}).appendTo($('#files_container')), | |
| img = $('<img/>').attr({'id': id_img, 'class': 'cropbox', 'src': file.url, 'style': 'display: none'}).appendTo($('#'+id_upload)); | |
| img.load(function(){ | |
| img_data[cropbox_indx] = {f_name: file.name, dimensions: {crop_w: crop_w, crop_h: crop_h}, coords: 0}; | |
| crop(id_img, img, cropbox_indx, img_data); // this function is below | |
| img_container.css({'width': img.width, 'height': img.height}); | |
| }); | |
| } | |
| }); | |
| } | |
| }); | |
| // initialize cropbox for each image | |
| function crop(id_img, img, cropbox_indx, img_data){ | |
| var proportion_coef = img_data[cropbox_indx].dimensions.crop_w/img_data[cropbox_indx].dimensions.crop_h, | |
| cx = img.width()/2, | |
| cy = img.height()/2; | |
| if (img.width() >= img.height()){ | |
| var h_crop = img.height()*0.7, | |
| w_crop = h_crop*proportion_coef, | |
| x = cx - w_crop/2, //this coords used to set default selection | |
| y = cy - h_crop/2, | |
| x2 = x + w_crop, | |
| y2 = y + h_crop; | |
| } else { | |
| w_crop = img.width()*0.7; | |
| h_crop = w_crop/proportion_coef; | |
| x = cx - w_crop/2; | |
| y = cy - h_crop/2; | |
| x2 = x + w_crop; | |
| y2 = y + h_crop; | |
| } | |
| var coords = {}; | |
| coords = {'x': x, 'y': y, 'w': (x2 - x), 'h': (y2 - y)}; | |
| img_data[cropbox_indx].coords = coords; | |
| $("#"+id_img).Jcrop({ | |
| onSelect: function(c){ | |
| coords.x = c.x; | |
| coords.y = c.y; | |
| coords.w = c.w; | |
| coords.h = c.h; | |
| img_data[cropbox_indx].coords = coords; | |
| }, | |
| aspectRatio: proportion_coef, | |
| bgOpacity:.2, | |
| boxWidth: 300, | |
| boxHeight: 300, | |
| setSelect: [x, y, x2, y2] | |
| }); | |
| } | |
| after this you need to post data to server: | |
| $('#crop').click(function(){ | |
| var img_data_arr = []; | |
| $.each(img_data, function(key, value){ | |
| var coords_arr = [], | |
| dimensions_arr = []; | |
| $.each(value.coords, function(key, value){ | |
| coords_arr.push('"'+key+'"'+':'+value); | |
| }); | |
| $.each(value.dimensions, function(key, value){ | |
| dimensions_arr.push('"'+key+'"'+':'+value); | |
| }); | |
| var id_json = '"'+key+'"'+':{"coords":{'+coords_arr.join(',')+'},"f_name":"'+value.f_name+'","dimensions":{'+dimensions_arr.join(',')+'}}'; | |
| img_data_arr.push(id_json); | |
| }); | |
| var img_data_json = '{'+img_data_arr.join(',')+'}'; | |
| $.post($('#fileupload').attr('action'), {img_data_json: img_data_json}, function(res){ | |
| var imgs = $.parseJSON(res); | |
| }); | |
| }); | |
| and on server i rewrite thumbnail, created by upload handler class | |
| public function crop(){ | |
| $img_data = json_decode(stripslashes($_POST['img_data_json'])); | |
| $imgs = array(); | |
| foreach ($img_data as $key => $value) { | |
| $img = $this->options['upload_dir'].$value->f_name; | |
| $thumb = $this->options['image_versions']['thumbnail']['upload_dir'].$value->f_name; | |
| if (exec('convert')){ | |
| exec("convert $img -crop {$value->coords->w}x{$value->coords->h}+{$value->coords->x}+{$value->coords->y}". | |
| " -resize {$value->dimensions->crop_w}x{$value->dimensions->crop_h} $thumb"); | |
| } else { | |
| $new_img = @imagecreatetruecolor($value->dimensions->crop_w, $value->dimensions->crop_h); | |
| $src_img = @imagecreatefromjpeg($img); | |
| list($img_width, $img_height) = @getimagesize($img); | |
| $write_image = 'imagejpeg'; | |
| @imagecopyresampled( | |
| $new_img, | |
| $src_img, | |
| 0, 0, $value->coords->x, $value->coords->y, | |
| $value->dimensions->crop_w, | |
| $value->dimensions->crop_h, | |
| $value->coords->w, | |
| $value->coords->h | |
| ); | |
| $write_image($new_img, $thumb); | |
| //Free up memory (imagedestroy does not delete files): | |
| @imagedestroy($src_img); | |
| @imagedestroy($new_img); | |
| } | |
| $image = array( | |
| 'name' => $value->f_name, | |
| 'image_url' => $this->options['upload_url'].$value->f_name, | |
| 'thumbnail_url' => $this->options['image_versions']['thumbnail']['upload_url'].$value->f_name | |
| ); | |
| $imgs[] = $image; | |
| } | |
| echo json_encode($imgs); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment