Closed aBrookland closed 8 years ago
Oh yes, with the changes to the process inline functionality so that croppic actually does the resize and crop in browser the server needs to be able to handle a different POST to the cropURL.
The resized and cropped image is uploaded as a data URI in the form data named croppedImage. This data URI needs to be saved as a binary file and not processed at all as it is the final cropped file.
So if processInline option is true and the processInlineFallback option is also true the server has to be able to handle all three possible routes:
So in this case your server side crop URL function needs to work something like this:
$imgUrl = $_POST['imgUrl'];
$input_uri = '';
$output_uri = '';
$got_input_file = FALSE;
$got_output_file = FALSE;
if(isset($_POST['croppedImage'])) {
// Final cropped image uploaded as a data URI
// so need to save the cropped image data URI as a binary file
// if any errors return error as JSON and don't continue
$output_uri = '{URL_OF_SAVED_FILE}';
$got_output_file = TRUE;
} elseif(preg_match('!^data:image/([^;]+);base64,(.+)$!', $imgUrl)) {
// Uncropped image uploaded as a data URI
// so need to save the uncropped image data URI as a binary file
// if any errors return error as JSON and don't continue
$input_uri = '{URL_OF_SAVED_FILE}';
$got_input_file = TRUE;
} else {
// Uncropped image was previously uploaded to the upload URL
$input_uri = $imgUrl;
$got_input_file = TRUE;
}
if($got_input_file) {
// need to crop the input file that is set in $input_uri
$output_uri = '{URL_OF_SAVED_CROPPED_FILE}';
$got_output_file = TRUE;
}
if(!$got_output_file) {
// No output file so return an error as JSON and don't continue
}
// cropped file has been created and saved to server so return success as JSON
And one final fix - I added a hidden input to the fallback IFrame that is used when ajax upload isn't supported to fix an error in IE where it would show a prompt to download file when receiving the JSON response from the server.
The hidden input has the name "fallbackIframe" and the value 1.
The server code then checks for the existence of fallbackIframe in the POST variables and adds the "Content-Type: text/plain" header which makes IE handle the response correctly.
Hi there, are you interested in helping me out by chance? I've got a simple site which uses another marquee tool and would like to replace it with Croppic. Sorry for asking here, don't know how to get in touch otherwise. Any help is appreciated. Cheers Denis
Hi Denis,
Sorry I'm too busy to really help - have you tried creating an issue detailing what you need help with or maybe tried stack overflow?
If not I suggest you do as I'd rather not derail this issue.
I found a couple of errors in the file validation function I added plus the file field reset I added to the upload button click handler didn't work in IE10 and needed a work around.
Here's an updated version - I forgot to say in the first post but I can't upload .js files so I've added .txt to the end, if anyone downloads the file to use just rename and remove the .txt extension.
Hi @aBrookland, is your coppic.js file a straight replac? I am having the issue on mobile devices with the image skewing and rotating after the image is cropped.
@smithead123 yes it is - sounds like you're having issues with EXIF orientation setting - we had it with iOS devices, they take the picture always one way (either portrait or landscape I forget which) and if you're holding the phone the other way it sets it in the EXIF data. The phone then shows you the image rotated based on the EXIF data even if you view it in a browser.
So we found that the image looked right when it was loaded into croppic but the cropped image was flipped. I've added code to check the EXIF data and correctly rotate the image before cropping.
If you want to try my version of the script as a replacement then you need to be aware of the changes to the POSTing behaviour I documented above - mainly that if you use the processInline option my version will now perform the crop in the browser and send back the cropped image as a data URI in a different POST variable called "croppedImage"
@aBrookland is there any way i can contact you directly - just have another couple of small questions. Thanks
@smithead123 - hmmm, I don't really want to advertise my email address on here and I can't see any way to private message through github?
So I guess your only option is to ask your questions here - at least then any answers I can provide will be available for others to see.
However I am very busy so I moght not be able to devote much, if any, time to answer you questions.
no problem, Im just implementing your soltuion, I have included the exif.js and canvasresize.js files, but I am now getting an error 'Uncaught TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'.' - Do you have a working zip file with all the package?
Oh - I completely forgot the reliance on exif.js, I better add that to my original post.
My code is wrapped up in a bespoke Drupal 7 webform component I've developed for a client's website.
I don't mind supplying you with a copy but it wouldn't be usable as is unless you've got a working Drupal 7 installation.
Alternatively I can just zip the croppic files including exif.js and canvas_resize.js if that's helpful.
That would be perfect if you could supply the croppic, exif and canvas please and any other dependancies and requirements - thanks again!
Here's my croppic folder as a zip (.txt extension added to fool the github filters) it contains the three javascript files plus the css and images
Thanks @aBrookland this is almost fully working! It now brings the image in from my iphone at the correct orientation and size, but it won't finalize the crop and i am now getting a different error:
I appreciate your help! Just making sure that other developers viewing this won't get the same issues!
What is the data that's being passed back from your site after processing the crop POST?
The error you're seeing is because it's not a valid JSON string.
im just using the exact files supplied, this function is inside croppic.js:
afterCrop: function(data) { var that = this; var response;
try {
response = $.parseJSON(data);
} catch (err) {
response = typeof data == 'object' ? data : $.parseJSON(data);
}
When you crop the image Croppic POSTs back to your site and expects a response in JSON format - that response is passed into the "afterCrop" function as the "data" argument.
So again what is the response returned from your site to he POST to /quiz/img_crop_to_file.php?
ah the data being passed into the afterCrop function is givin the value 'image type not supported'
Right - croppic requires that all data passed back to it from the server is a JSON encoded string which is all detailed in the croppic set up guide but basically you need to pass back an object with a "status" property set to either "success" or "error".
If it's a success then the object also needs a "url" property which is the URL to the saved cropped image on your site.
Otherwise if it's a failure then the object needs a "message" property where you set the error message.
If your site is in PHP then probably the easiest way to pass back JSON data is like so:
$response = array(
'status' => 'success',
'url' => 'PATH/TO/CROPPED/IMAGE/ON/SERVER',
);
echo json_encode($response);
Ok @aBrookland I appreciate your assistance it- may be easier to attach my local copy- this is bascially croppic default files - with your replaced includes. test.zip.txt
Ah I see - you've just got the example crop php script file supplied on the Croppic site.
That file is written to work when processInline option is set to false and then the image is uploaded by a POST to the uploadURL script and saved on the server and that temp file is then cropped in the crop script.
To use processInline: true you need to rewrite the crop php script to be able to accept the image POSTed back as a data URI.
I haven't got time to rewrite the script for you, see my comment above for the basic outline of what to change.
To save a data URI use code like this - assuming you've set the image data into the variable $image_data and the output server path including the filename but not extension into $filename.
if(preg_match('!^data:image/([^;]+);base64,.+$!', $image_data, $matches)) {
$binary_data = file_get_contents($image_data);
$extension = $matches[1] == 'jpeg' ? 'jpg' : $matches[1];
file_put_contents($filename . $extension, $binary_data);
}
You'd need to add this code into the two places with the comment "so need to save the cropped image data URI as a binary file". For the pre cropped image you'd set $image_data = $_POST['croppedImage'], for the uncropped image you'd set it to $imgUrl.
Also for the pre cropped image you are saving the final image so $filename = $output_filename but for the uncropped image you need to save it with a different file name so it's saved somewhere ready to be processed later in the script
Think this is the end of the road, so near - yet so far. Thanks for your help anyway but i'm struggling to get this running.
I found some issues with the zooming code so I've rewritten it including removing the scaleToFill option and replacing it with allowUpscaleBeyondCropSize option.
Now croppic will always zoom the image to fit in the crop size but will only allow the user to zoom in and upscale the image if allowUpscaleBeyondCropSize is true.
Also added Math.floor() to crop height and width calculations as I found that sometimes the calculated crop size would end up fractionally bigger than the actual image size and cause an index out of bounds error.
Updated first post with latest version of the script (v1.4).
I've added one more feature - an undo button that appears after cropping and reloads the original uncropped image to save the user having to reselect and potentially re-upload the original image if they aren't happy with the crop.
This comes with a new undoControl option (default: false) - boolean, controls whether to add the undo button.
Updated first post with v1.5 of the script.
And we've gone live with the widget at https://www.scotrail.co.uk/club50/form?open=webform-ttlc-register-wrapper where you can see it in action.
We use webcam.js and jquery.facedetection.js alongside our modified croppic.js all wrapped up in a custom Drupal webform component module.
Hello,
nice work. I am deciding to use your modified croppic version. Could you perhaps put your version into a separate git repo? It does not seem to be further developed by the original dev. And it would be really nice if you set up a Bower dependency and/or Composer dependancy.
Thx a million
@MacGyer OK, I've forked croppic to https://github.com/aBrookland/croppic and pushed my changes to it. I haven't had time to modify img_save_to_file.php and img_crop_to_file.php to handle my changes yet.
They both need to handle the IE IFrame mimetype issue and uploading files by data URI plus img_crop_to_file.php needs to handle the image cropped in browser.
One good thing about doing as you requested is that it made me realise I'd forgotten that I'd modified croppic.css and cropperIcons.png so the updated versions of those files are available from my repository.
You can pass a variable adding:
On the upload image uploadData:{ 'id': $('#id').val() },
if you want on the crop image cropData:{ 'id': $('#id').val() },
Insert a input to make the POST variable and add on the file img_crop_to_file or img_save_to_file
$value= $_POST["id"]; $output_filename = "images/$value";
Can we crop image without using a server-side script?
Hi,
I've used your script as part of a solution to provide a widget for users to provide a passport photo for an ID card.
I've had to add some extra config options and additions to get it working how we needed so I thought I'd supply our modified version for you to look at and use anything you want. I've also reformatted and added missing braces etc to pass JSHint linting.
We've tested successfully on IE8, IE9, IE10, IE11 and Edge (all Win only) plus Firefox (Win and Mac), Chrome (Win, Mac, Android, iPhone and iPad), Safari (Mac, iPhone and iPad).
Sorry we've not had time to fork the project and provide proper atomic commits and generate pull requests which would've made your life easier but we've been working to a tight deadline.
Modifications:
Current version (1.5): croppic.js.txt