From 56171fb0607098eca436cb5e6a5a893f4991edf1 Mon Sep 17 00:00:00 2001 From: "Hermann D. Schimpf" Date: Wed, 28 May 2014 17:09:55 -0400 Subject: [PATCH 1/7] + Rotation support --- assets/css/croppic.css | 2 ++ assets/img/cropperIcons.png | Bin 4773 -> 4598 bytes croppic.js | 46 +++++++++++++++++++++++++++++------- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/assets/css/croppic.css b/assets/css/croppic.css index f354a52..fa78d82 100644 --- a/assets/css/croppic.css +++ b/assets/css/croppic.css @@ -74,6 +74,8 @@ .cropControls i.cropControlZoomIn{ background-position:-30px 0px; } .cropControls i.cropControlZoomOut{ background-position:-60px 0px; } .cropControls i.cropControlZoomMuchOut{ background-position:-90px 0px; } + .cropControls i.cropControlRotateLeft{ background-position:-210px 0px; } + .cropControls i.cropControlRotateRight{ background-position:-240px 0px; } .cropControls i.cropControlCrop{ background-position:-120px 0px;} .cropControls i.cropControlUpload{ background-position:-150px 0px;} .cropControls i.cropControlReset{ background-position:-180px 0px;} diff --git a/assets/img/cropperIcons.png b/assets/img/cropperIcons.png index 7bbc200d5e272248dc91875b687c84ae84f5b64c..e94bfcccae15bc808cd3ca3ad847ce7c6145e480 100644 GIT binary patch literal 4598 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 literal 4773 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'; } - else{ html = '
' + cropControlZoomIn + cropControlZoomOut + cropControlCrop + cropControlReset + '
'; } + if(that.options.doubleZoomControls){ html = '
'+ cropControlZoomMuchIn + cropControlZoomIn + cropControlZoomOut + cropControlZoomMuchOut + cropControlRotateLeft + cropControlRotateRight + cropControlCrop + cropControlReset + '
'; } + else{ html = '
' + cropControlZoomIn + cropControlZoomOut + cropControlRotateLeft + cropControlRotateRight + cropControlCrop + cropControlReset + '
'; } that.obj.append(html); @@ -285,7 +294,13 @@ that.cropControlZoomOut = that.cropControlsCrop.find('.cropControlZoomOut'); that.cropControlZoomOut.on('click',function(){ that.zoom(-that.options.zoomFactor); }); - that.cropControlCrop = that.cropControlsCrop.find('.cropControlCrop'); + that.cropControlZoomIn = that.cropControlsCrop.find('.cropControlRotateLeft'); + that.cropControlZoomIn.on('click', function() { that.rotate(-that.options.rotateFactor); }); + + that.cropControlZoomOut = that.cropControlsCrop.find('.cropControlRotateRight'); + that.cropControlZoomOut.on('click', function() { that.rotate(that.options.rotateFactor); }); + + that.cropControlCrop = that.cropControlsCrop.find('.cropControlCrop'); that.cropControlCrop.on('click',function(){ that.crop(); }); that.cropControlReset = that.cropControlsCrop.find('.cropControlReset'); @@ -336,6 +351,17 @@ }); }, + rotate: function(x) { + var that = this; + that.actualRotation += x; + that.img.css({ + '-webkit-transform': 'rotate(' + that.actualRotation + 'deg)', + '-moz-transform': 'rotate(' + that.actualRotation + 'deg)', + 'transform': 'rotate(' + that.actualRotation + 'deg)', + }); + if (typeof that.options.onImgRotate == 'function') + that.options.onImgRotate.call(that); + }, zoom :function(x){ var that = this; var ratio = that.imgW / that.imgH; @@ -418,7 +444,8 @@ imgY1:Math.abs( parseInt( that.img.css('top') ) ), imgX1:Math.abs( parseInt( that.img.css('left') ) ), cropH:that.objH, - cropW:that.objW + cropW:that.objW, + rotation:that.actualRotation }; var formData = new FormData(); @@ -490,7 +517,8 @@ that.obj.append(that.croppedImg); if(that.options.outputUrlId !== ''){ $('#'+that.options.outputUrlId).val(that.croppedImg.attr('url')); } } - + if (typeof that.options.onReset == 'function') + that.options.onReset.call(that); }, destroy:function(){ var that = this; From 2cf142de8a7c0ee78a3e4ccaf29a4fb6517aaed3 Mon Sep 17 00:00:00 2001 From: "Hermann D. Schimpf" Date: Wed, 28 May 2014 17:19:24 -0400 Subject: [PATCH 2/7] + Eyecandy rotation + PHP crop rotation process --- croppic.js | 7 +++++++ img_crop_to_file.php | 23 +++++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/croppic.js b/croppic.js index bce2850..f4fc0eb 100644 --- a/croppic.js +++ b/croppic.js @@ -359,6 +359,13 @@ '-moz-transform': 'rotate(' + that.actualRotation + 'deg)', 'transform': 'rotate(' + that.actualRotation + 'deg)', }); + if(that.options.imgEyecandy) { + that.imgEyecandy.css({ + '-webkit-transform': 'rotate(' + that.actualRotation + 'deg)', + '-moz-transform': 'rotate(' + that.actualRotation + 'deg)', + 'transform': 'rotate(' + that.actualRotation + 'deg)', + }); + } if (typeof that.options.onImgRotate == 'function') that.options.onImgRotate.call(that); }, diff --git a/img_crop_to_file.php b/img_crop_to_file.php index 200462c..b2b7052 100644 --- a/img_crop_to_file.php +++ b/img_crop_to_file.php @@ -12,6 +12,7 @@ $imgX1 = $_POST['imgX1']; $cropW = $_POST['cropW']; $cropH = $_POST['cropH']; +$angle = $_POST['rotation']; $jpeg_quality = 100; @@ -37,22 +38,24 @@ break; default: die('image type not supported'); } - + $resizedImage = imagecreatetruecolor($imgW, $imgH); - imagecopyresampled($resizedImage, $source_image, 0, 0, 0, 0, $imgW, - $imgH, $imgInitW, $imgInitH); - - + imagecopyresampled($resizedImage, $source_image, 0, 0, 0, 0, $imgW, + $imgH, $imgInitW, $imgInitH); + + $dest_image = imagecreatetruecolor($cropW, $cropH); - imagecopyresampled($dest_image, $resizedImage, 0, 0, $imgX1, $imgY1, $cropW, - $cropH, $cropW, $cropH); + imagecopyresampled($dest_image, $resizedImage, 0, 0, $imgX1, $imgY1, $cropW, + $cropH, $cropW, $cropH); + + // image rotation + $rotated_image = imagerotate($dest_image, $angle, 0); + imagejpeg($rotated_image, $output_filename.$type, $jpeg_quality); - imagejpeg($dest_image, $output_filename.$type, $jpeg_quality); - $response = array( "status" => 'success', - "url" => $output_filename.$type + "url" => $output_filename.$type ); print json_encode($response); From 9437e0c6c54d4aff0f0cc2bd2832aeea5ebf3dd2 Mon Sep 17 00:00:00 2001 From: "Hermann D. Schimpf" Date: Thu, 29 May 2014 09:45:19 -0400 Subject: [PATCH 3/7] FIX: check if Eyecandy is active before call hide() --- croppic.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/croppic.js b/croppic.js index f4fc0eb..19d490c 100644 --- a/croppic.js +++ b/croppic.js @@ -480,8 +480,9 @@ }).always(function(data){ response = jQuery.parseJSON(data); if(response.status=='success'){ - - that.imgEyecandy.hide(); + // FIX: check if Eyecandy is active + if (that.options.imgEyecandy) + that.imgEyecandy.hide(); that.destroy(); From 59835b84339d003ed8d72395540047e5cf79c46a Mon Sep 17 00:00:00 2001 From: "Hermann D. Schimpf" Date: Thu, 29 May 2014 09:46:36 -0400 Subject: [PATCH 4/7] PHP rotation processing --- img_crop_to_file.php | 49 +++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/img_crop_to_file.php b/img_crop_to_file.php index b2b7052..5fc2d2d 100644 --- a/img_crop_to_file.php +++ b/img_crop_to_file.php @@ -4,17 +4,22 @@ */ $imgUrl = $_POST['imgUrl']; +// original sizes $imgInitW = $_POST['imgInitW']; $imgInitH = $_POST['imgInitH']; +// resized sizes $imgW = $_POST['imgW']; $imgH = $_POST['imgH']; +// offsets $imgY1 = $_POST['imgY1']; $imgX1 = $_POST['imgX1']; +// crop box $cropW = $_POST['cropW']; $cropH = $_POST['cropH']; +// rotation angle $angle = $_POST['rotation']; -$jpeg_quality = 100; +$png_quality = 9; $output_filename = "temp/croppedImg_".rand(); @@ -39,24 +44,34 @@ default: die('image type not supported'); } - $resizedImage = imagecreatetruecolor($imgW, $imgH); - imagecopyresampled($resizedImage, $source_image, 0, 0, 0, 0, $imgW, - $imgH, $imgInitW, $imgInitH); + // resize the original image to size of editor + $resizedImage = imagecreatetruecolor($imgW, $imgH); + imagecopyresampled($resizedImage, $source_image, 0, 0, 0, 0, $imgW, $imgH, $imgInitW, $imgInitH); + // rotate the rezized image + $rotated_image = imagerotate($resizedImage, -$angle, 0); + // find new width & height of rotated image + $rotated_width = imagesx($rotated_image); + $rotated_height = imagesy($rotated_image); + // diff between rotated & original sizes + $dx = $rotated_width - $imgW; + $dy = $rotated_height - $imgH; - $dest_image = imagecreatetruecolor($cropW, $cropH); - imagecopyresampled($dest_image, $resizedImage, 0, 0, $imgX1, $imgY1, $cropW, - $cropH, $cropW, $cropH); + // crop rotated image to fit into original rezized rectangle + $cropped_rotated_image = imagecreatetruecolor($imgW, $imgH); + imagecolortransparent($cropped_rotated_image, imagecolorallocate($cropped_rotated_image, 0, 0, 0)); + imagecopyresampled($cropped_rotated_image, $rotated_image, 0, 0, $dx / 2, $dy / 2, $imgW, $imgH, $imgW, $imgH); - // image rotation - $rotated_image = imagerotate($dest_image, $angle, 0); + // crop image into selected area + $final_image = imagecreatetruecolor($cropW, $cropH); + imagecolortransparent($final_image, imagecolorallocate($final_image, 0, 0, 0)); + imagecopyresampled($final_image, $cropped_rotated_image, 0, 0, $imgX1, $imgY1, $cropW, $cropH, $cropW, $cropH); - imagejpeg($rotated_image, $output_filename.$type, $jpeg_quality); + // finally output png image + imagepng($final_image, $output_filename.$type, $png_quality); - $response = array( - "status" => 'success', - "url" => $output_filename.$type - ); - print json_encode($response); - -?> \ No newline at end of file + $response = Array( + "status" => 'success', + "url" => $output_filename.$type + ); + print json_encode($response); \ No newline at end of file From 352521fd1af1b201ae0c03535b91448ac516ac7d Mon Sep 17 00:00:00 2001 From: Paris Theofanidis Date: Wed, 25 Jun 2014 18:32:18 +0200 Subject: [PATCH 5/7] image is js managed + php only resizes and crops due to increased quality --- .gitignore | 1 + croppic.js | 295 ++++++++++++++++++++----------------------- img_crop_to_file.php | 48 ++++--- index.html | 2 +- 4 files changed, 160 insertions(+), 186 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/croppic.js b/croppic.js index e94b904..8426b5e 100644 --- a/croppic.js +++ b/croppic.js @@ -42,7 +42,7 @@ // INIT THE WHOLE DAMN THING!!! that.init(); - + }; Croppic.prototype = { @@ -70,160 +70,135 @@ cropControlZoomIn:{}, cropControlZoomOut:{}, cropControlCrop:{}, - cropControlReset:{}, - cropControlRemoveCroppedImage:{}, + cropControlReset:{}, + cropControlRemoveCroppedImage:{}, modal:{}, loader:{}, - + init: function () { var that = this; - + that.objW = that.obj.width(); that.objH = that.obj.height(); - + if( $.isEmptyObject(that.defaultImg)){ that.defaultImg = that.obj.find('img'); } - + that.createImgUploadControls(); that.bindImgUploadControl(); - + }, createImgUploadControls: function(){ var that = this; - + var cropControlUpload = ''; if(that.options.customUploadButtonId ===''){ cropControlUpload = ''; } var cropControlRemoveCroppedImage = ''; - + if( $.isEmptyObject(that.croppedImg)){ cropControlRemoveCroppedImage=''; } var html = '
' + cropControlUpload + cropControlRemoveCroppedImage + '
'; that.outputDiv.append(html); - + that.cropControlsUpload = that.outputDiv.find('.cropControlsUpload'); - + if(that.options.customUploadButtonId ===''){ that.imgUploadControl = that.outputDiv.find('.cropControlUpload'); } else{ that.imgUploadControl = $('#'+that.options.customUploadButtonId); that.imgUploadControl.show(); } if( !$.isEmptyObject(that.croppedImg)){ that.cropControlRemoveCroppedImage = that.outputDiv.find('.cropControlRemoveCroppedImage'); } - + }, bindImgUploadControl: function(){ - + var that = this; - + // CREATE UPLOAD IMG FORM var formHtml = ''; that.outputDiv.append(formHtml); that.form = that.outputDiv.find('.'+that.id+'_imgUploadForm'); - + that.imgUploadControl.off('click'); - that.imgUploadControl.on('click',function(){ - that.form.find('input[type="file"]').trigger('click'); - }); - + that.imgUploadControl.on('click',function(){ + that.form.find('input[type="file"]').trigger('click'); + }); + if( !$.isEmptyObject(that.croppedImg)){ - - that.cropControlRemoveCroppedImage.on('click',function(){ + + that.cropControlRemoveCroppedImage.on('click',function(){ that.croppedImg.remove(); $(this).hide(); - - if( !$.isEmptyObject(that.defaultImg)){ + + if( !$.isEmptyObject(that.defaultImg)){ that.obj.append(that.defaultImg); } - + if(that.options.outputUrlId !== ''){ $('#'+that.options.outputUrlId).val(''); } - - }); - + + }); + } - - that.form.find('input[type="file"]').change(function(){ - - if (that.options.onBeforeImgUpload) that.options.onBeforeImgUpload.call(that); - - that.showLoader(); - that.imgUploadControl.hide(); - - var formData = new FormData(that.form[0]); - - for (var key in that.options.uploadData) { - if( that.options.uploadData.hasOwnProperty(key) ) { - formData.append( key , that.options.uploadData[key] ); - } - } - - $.ajax({ - url: that.options.uploadUrl, - data: formData, - context: document.body, - cache: false, - contentType: false, - processData: false, - type: 'POST' - }).always(function(data){ - response = jQuery.parseJSON(data); - if(response.status=='success'){ - - that.imgInitW = that.imgW = response.width; - that.imgInitH = that.imgH = response.height; - - if(that.options.modal){ that.createModal(); } - if( !$.isEmptyObject(that.croppedImg)){ that.croppedImg.remove(); } - - that.imgUrl=response.url; - - that.obj.append(''); - that.initCropper(); - - that.hideLoader(); - if (that.options.onAfterImgUpload) that.options.onAfterImgUpload.call(that); - - } - - if(response.status=='error'){ - that.obj.append('

'+response.message+'

'); - that.hideLoader(); - setTimeout( function(){ that.reset(); },2000) - } - + that.form.find('input[type="file"]').change(function(e){ - }); - + if (that.options.onBeforeImgUpload) that.options.onBeforeImgUpload.call(that); + + that.showLoader(); + that.imgUploadControl.hide(); + + var reader = new FileReader(); + reader.onload = function(e){ + var img = new Image(); + img.onload = function(){ + that.imgInitW = that.imgW = this.width; + that.imgInitH = that.imgH = this.height; + + if(that.options.modal) + that.createModal(); + + if( !$.isEmptyObject(that.croppedImg)){ that.croppedImg.remove(); } + + that.imgUrl = e.target.result; + that.obj.append(''); + that.initCropper(); + that.hideLoader(); + if (that.options.onAfterImgUpload) + that.options.onAfterImgUpload.call(that); + } + img.src = e.target.result; + } + reader.readAsDataURL(e.target.files[0]); }); - }, createModal: function(){ var that = this; - + var marginTop = that.windowH/2-that.objH/2; var modalHTML = '
'+'
'+'
'; $('body').append(modalHTML); - + that.modal = $('#croppicModal'); - + that.obj = $('#croppicModalObj'); - + }, destroyModal: function(){ var that = this; - + that.obj = that.outputDiv; that.modal.remove(); }, initCropper: function(){ var that = this; - + /*SET UP SOME VARS*/ that.img = that.obj.find('img'); that.img.wrap('
'); - + /*INIT DRAGGING*/ that.createCropControls(); - + if(that.options.imgEyecandy){ that.createEyecandy(); } that.initDrag(); that.initialScaleImg(); @@ -242,17 +217,17 @@ var that = this; that.zoom(-that.imgInitW); that.zoom(40); - + // initial center image - + that.img.css({'left': -(that.imgW -that.objW)/2, 'top': -(that.imgH -that.objH)/2, 'position':'relative'}); if(that.options.imgEyecandy){ that.imgEyecandy.css({'left': -(that.imgW -that.objW)/2, 'top': -(that.imgH -that.objH)/2, 'position':'relative'}); } - + }, - + createCropControls: function(){ var that = this; - + // CREATE CONTROLS var cropControlZoomMuchIn = ''; var cropControlZoomIn = ''; @@ -260,43 +235,43 @@ var cropControlZoomMuchOut = ''; var cropControlCrop = ''; var cropControlReset = ''; - + var html; - + if(that.options.doubleZoomControls){ html = '
'+ cropControlZoomMuchIn + cropControlZoomIn + cropControlZoomOut + cropControlZoomMuchOut + cropControlCrop + cropControlReset + '
'; } - else{ html = '
' + cropControlZoomIn + cropControlZoomOut + cropControlCrop + cropControlReset + '
'; } - + else{ html = '
' + cropControlZoomIn + cropControlZoomOut + cropControlCrop + cropControlReset + '
'; } + that.obj.append(html); - + that.cropControlsCrop = that.obj.find('.cropControlsCrop'); // CACHE AND BIND CONTROLS if(that.options.doubleZoomControls){ that.cropControlZoomMuchIn = that.cropControlsCrop.find('.cropControlZoomMuchIn'); that.cropControlZoomMuchIn.on('click',function(){ that.zoom( that.options.zoomFactor*10 ); }); - + that.cropControlZoomMuchOut = that.cropControlsCrop.find('.cropControlZoomMuchOut'); that.cropControlZoomMuchOut.on('click',function(){ that.zoom(-that.options.zoomFactor*10); }); } - + that.cropControlZoomIn = that.cropControlsCrop.find('.cropControlZoomIn'); that.cropControlZoomIn.on('click',function(){ that.zoom(that.options.zoomFactor); }); that.cropControlZoomOut = that.cropControlsCrop.find('.cropControlZoomOut'); - that.cropControlZoomOut.on('click',function(){ that.zoom(-that.options.zoomFactor); }); + that.cropControlZoomOut.on('click',function(){ that.zoom(-that.options.zoomFactor); }); that.cropControlCrop = that.cropControlsCrop.find('.cropControlCrop'); that.cropControlCrop.on('click',function(){ that.crop(); }); that.cropControlReset = that.cropControlsCrop.find('.cropControlReset'); - that.cropControlReset.on('click',function(){ that.reset(); }); - + that.cropControlReset.on('click',function(){ that.reset(); }); + }, initDrag:function(){ var that = this; - + that.img.on("mousedown", function(e) { - + e.preventDefault(); // disable selection var z_idx = that.img.css('z-index'), @@ -304,37 +279,37 @@ drg_w = that.img.outerWidth(), pos_y = that.img.offset().top + drg_h - e.pageY, pos_x = that.img.offset().left + drg_w - e.pageX; - + that.img.css('z-index', 1000).on("mousemove", function(e) { - + var imgTop = e.pageY + pos_y - drg_h; var imgLeft = e.pageX + pos_x - drg_w; - + that.img.offset({ top:imgTop, left:imgLeft }).on("mouseup", function() { $(this).removeClass('draggable').css('z-index', z_idx); }); - + if(that.options.imgEyecandy){ that.imgEyecandy.offset({ top:imgTop, left:imgLeft }); } - + if( parseInt( that.img.css('top')) > 0 ){ that.img.css('top',0); if(that.options.imgEyecandy){ that.imgEyecandy.css('top', 0); } } var maxTop = -( that.imgH-that.objH); if( parseInt( that.img.css('top')) < maxTop){ that.img.css('top', maxTop); if(that.options.imgEyecandy){ that.imgEyecandy.css('top', maxTop); } } - + if( parseInt( that.img.css('left')) > 0 ){ that.img.css('left',0); if(that.options.imgEyecandy){ that.imgEyecandy.css('left', 0); }} var maxLeft = -( that.imgW-that.objW); if( parseInt( that.img.css('left')) < maxLeft){ that.img.css('left', maxLeft); if(that.options.imgEyecandy){ that.imgEyecandy.css('left', maxLeft); } } - + if (that.options.onImgDrag) that.options.onImgDrag.call(that); - + }); - + }).on("mouseup", function() { that.img.off("mousemove"); }).on("mouseout", function() { that.img.off("mousemove"); }); - + }, zoom :function(x){ var that = this; @@ -342,73 +317,73 @@ var newWidth = that.imgW+x; var newHeight = newWidth/ratio; var doPositioning = true; - + if( newWidth < that.objW || newHeight < that.objH){ - - if( newWidth - that.objW < newHeight - that.objH ){ + + if( newWidth - that.objW < newHeight - that.objH ){ newWidth = that.objW; newHeight = newWidth/ratio; }else{ newHeight = that.objH; newWidth = ratio * newHeight; } - + doPositioning = false; - - } - + + } + if( newWidth > that.imgInitW || newHeight > that.imgInitH){ - - if( newWidth - that.imgInitW < newHeight - that.imgInitH ){ + + if( newWidth - that.imgInitW < newHeight - that.imgInitH ){ newWidth = that.imgInitW; newHeight = newWidth/ratio; }else{ newHeight = that.imgInitH; newWidth = ratio * newHeight; } - + doPositioning = false; - + } - + that.imgW = newWidth; - that.img.width(newWidth); - + that.img.width(newWidth); + that.imgH = newHeight; - that.img.height(newHeight); - + that.img.height(newHeight); + var newTop = parseInt( that.img.css('top') ) - x/2; var newLeft = parseInt( that.img.css('left') ) - x/2; - + if( newTop>0 ){ newTop=0;} if( newLeft>0 ){ newLeft=0;} - + var maxTop = -( newHeight-that.objH); if( newTop < maxTop){ newTop = maxTop; } var maxLeft = -( newWidth-that.objW); if( newLeft < maxLeft){ newLeft = maxLeft; } - + if( doPositioning ){ - that.img.css({'top':newTop, 'left':newLeft}); + that.img.css({'top':newTop, 'left':newLeft}); } - + if(that.options.imgEyecandy){ that.imgEyecandy.width(newWidth); that.imgEyecandy.height(newHeight); if( doPositioning ){ - that.imgEyecandy.css({'top':newTop, 'left':newLeft}); + that.imgEyecandy.css({'top':newTop, 'left':newLeft}); } - } - + } + if (that.options.onImgZoom) that.options.onImgZoom.call(that); }, crop:function(){ var that = this; - + if (that.options.onBeforeImgCrop) that.options.onBeforeImgCrop.call(that); - + that.cropControlsCrop.hide(); that.showLoader(); - + var cropData = { imgUrl:that.imgUrl, imgInitW:that.imgInitW, @@ -420,7 +395,7 @@ cropH:that.objH, cropW:that.objW }; - + var formData = new FormData(); for (var key in cropData) { @@ -428,7 +403,7 @@ formData.append( key , cropData[key] ); } } - + for (var key in that.options.cropData) { if( that.options.cropData.hasOwnProperty(key) ) { formData.append( key , that.options.cropData[key] ); @@ -446,51 +421,51 @@ }).always(function(data){ response = jQuery.parseJSON(data); if(response.status=='success'){ - + that.imgEyecandy.hide(); - + that.destroy(); - + that.obj.append(''); if(that.options.outputUrlId !== ''){ $('#'+that.options.outputUrlId).val(response.url); } - + that.croppedImg = that.obj.find('.croppedImg'); that.init(); - + that.hideLoader(); } if(response.status=='error'){ that.obj.append('

'); } - + if (that.options.onAfterImgCrop) that.options.onAfterImgCrop.call(that); - + }); }, showLoader:function(){ var that = this; - + that.obj.append(that.options.loaderHtml); that.loader = that.obj.find('.loader'); - + }, hideLoader:function(){ var that = this; - that.loader.remove(); + that.loader.remove(); }, reset:function(){ var that = this; that.destroy(); - + that.init(); - - if( !$.isEmptyObject(that.croppedImg)){ - that.obj.append(that.croppedImg); + + if( !$.isEmptyObject(that.croppedImg)){ + that.obj.append(that.croppedImg); if(that.options.outputUrlId !== ''){ $('#'+that.options.outputUrlId).val(that.croppedImg.attr('url')); } } - + }, destroy:function(){ var that = this; diff --git a/img_crop_to_file.php b/img_crop_to_file.php index 200462c..69dfa95 100644 --- a/img_crop_to_file.php +++ b/img_crop_to_file.php @@ -15,45 +15,43 @@ $jpeg_quality = 100; -$output_filename = "temp/croppedImg_".rand(); - $what = getimagesize($imgUrl); switch(strtolower($what['mime'])) { case 'image/png': - $img_r = imagecreatefrompng($imgUrl); $source_image = imagecreatefrompng($imgUrl); - $type = '.png'; break; case 'image/jpeg': - $img_r = imagecreatefromjpeg($imgUrl); $source_image = imagecreatefromjpeg($imgUrl); - $type = '.jpeg'; break; case 'image/gif': - $img_r = imagecreatefromgif($imgUrl); $source_image = imagecreatefromgif($imgUrl); - $type = '.gif'; break; - default: die('image type not supported'); + default: + echo json_encode(array( + 'success' => false, + 'message' => 'image type not supported', + )); + return; } - $resizedImage = imagecreatetruecolor($imgW, $imgH); - imagecopyresampled($resizedImage, $source_image, 0, 0, 0, 0, $imgW, - $imgH, $imgInitW, $imgInitH); - - - $dest_image = imagecreatetruecolor($cropW, $cropH); - imagecopyresampled($dest_image, $resizedImage, 0, 0, $imgX1, $imgY1, $cropW, - $cropH, $cropW, $cropH); +$resizedImage = imagecreatetruecolor($imgW, $imgH); +imagecopyresampled($resizedImage, $source_image, 0, 0, 0, 0, $imgW, + $imgH, $imgInitW, $imgInitH); - imagejpeg($dest_image, $output_filename.$type, $jpeg_quality); - - $response = array( - "status" => 'success', - "url" => $output_filename.$type - ); - print json_encode($response); +$dest_image = imagecreatetruecolor($cropW, $cropH); +imagecopyresampled($dest_image, $resizedImage, 0, 0, $imgX1, $imgY1, $cropW, + $cropH, $cropW, $cropH); + + +ob_start(); +imagejpeg($dest_image, null, $jpeg_quality); +$imgData = ob_get_clean(); +ob_end_clean(); -?> \ No newline at end of file +$response = array( + "status" => 'success', + "url" => 'data:'.$what['mime'].';base64,'.base64_encode($imgData), + ); + echo json_encode($response); \ No newline at end of file diff --git a/index.html b/index.html index ff7fa0e..c1ff496 100644 --- a/index.html +++ b/index.html @@ -460,7 +460,7 @@

- +