6

I am using jQuery Croppie lib for cropping user's uploaded file. When user uploads file, I am opening modal in which user can crop image. After that I want to set this cropped image as file input value so that, user can submit form then when everything is ready, but I don't know how to "set" cropped image as input value.

Here is my code.

$scope.openCropModal = function(files) {
            if (!(files[0] instanceof Object) || (fileUploadMaxSize * 1100000) < files[0].size) {
                Alertify.alert('File size must be less than ' + fileUploadMaxSize + 'mb');

                return false;
            }
            $('#cropLogoModal').modal({});

            var $uploadCrop = $('#cropperMainContainer').croppie({
                viewport: {
                    width: 200,
                    height: 200,
                    type: 'square'
                },
                boundary: {
                    width: 300,
                    height: 300
                },
                enableExif: true,
                enableOrientation: true,
                orientation: 4,
            });

            var reader = new FileReader();

            reader.onload = function (e) {
                $uploadCrop.croppie('bind', {
                    url: e.target.result
                }).then(function() {

                });

            };

            reader.readAsDataURL(files[0]);

            $('#ready').on('click', function() {
                $uploadCrop.croppie('result', 'blob').then(function(blob) {

                });
            });

            $('.vanilla-rotate').on('click', function() {
                $uploadCrop.croppie('rotate', parseInt($(this).data('deg')));
            });
        }
Hamed Hajiloo
  • 964
  • 1
  • 10
  • 31
Aram810
  • 619
  • 7
  • 21
  • How are you sending this form ? Through ajax or default HTML actions ? – Kaiido Apr 18 '17 at 07:26
  • Default HTML form submit – Aram810 Apr 18 '17 at 07:27
  • Too bad ... Then the hackish dataURI empty field is your only way... For future readers which can send through ajax, create a FormData object and append your blob version of the canvas in there, so it is uploaded as multipart like should be any binary data. – Kaiido Apr 18 '17 at 07:30
  • Ps: You can't programaticaly change the value of an input type file except to reset it. – Kaiido Apr 18 '17 at 07:38

1 Answers1

3

Instead of putting it as file attachment, create hidden field for bas64 encoded blob data.

        var reader = new FileReader();

        reader.onload = function (e) {
            $uploadCrop.croppie('bind', {
                url: e.target.result
            }).then(function(blob) {
                $('#hiddenContent').val(btoa(blob));
            });
        };

And than when on server side, read this base64 encoded image content and put it to new file.

Warning Code not tested.

Justinas
  • 41,402
  • 5
  • 66
  • 96
  • If the form is sent through ajax, this solution is really ugly ! – Kaiido Apr 18 '17 at 07:27
  • @Kaiido Yes, because you already have FileReader object that you can use together with FormData, but OP is using **Default HTML form submit** – Justinas Apr 18 '17 at 07:29
  • Hum nope for the first part : OP is using FileReader to pass its File to the croppy lib (btw I wonder if it doens't accept a Blob directly, or at least a blobURI) but the lib seems to return a Blob, so yes a FormData would definitely be the best option here. And It wasn't clear OP was using default HTML form submit, I may have missed it in original post. – Kaiido Apr 18 '17 at 07:32
  • Oh and if the return value of the lib is really a Blob object, your code won't work : `btoa(blob)` => `'W29iamVjdCBCbG9iXQ=='` ;-) – Kaiido Apr 18 '17 at 07:36
  • 2
    My lib returns base64 as well as blob. I'm just wondering whether it is possible to do this using just my file input. – Aram810 Apr 18 '17 at 07:37