在 Dropzone.js 之前使用 cropper.js 将图像发送到服务器

Using cropper.js before Dropzone.js send image to server

我想在这里做的是在Dropzone.js将拖放的图像发送到服务器之前,出现一个带有cropper.js(fengyuanchen脚本)的模态,以便用户可以裁剪图像,当图像裁剪后,用 Dropzone.js 发送到服务器。

因此,当我使用函数 fileToBase64 更改#cropbox 的图像 src 并将裁剪器的图像替换为函数 cropper('replace') 时,它一直显示 default.jpg 图像,而不是用户上传的新的

HTML

<div class="wrapper-crop-box">
    <div class="crop-box">
        <img src="default.jpg" alt="Cropbox" id="cropbox">
    </div>
</div>

JS:

function fileToBase64(file) {
  var preview = document.querySelector('.crop-box img');
  var reader  = new FileReader();

  reader.onloadend = function () {
    preview.src = reader.result;
  }

  if (file) {
    reader.readAsDataURL(file);
  } else {
    preview.src = "";
  }
}

$(function() {
    Dropzone.options.avtDropzone = {
        acceptedFiles: 'image/*',
        autoProcessQueue: true,
        paramName: 'file',
        maxFilesize: 2,
        maxFiles: 1,
        thumbnailWidth: 200,
        thumbnailHeight: 200,
        accept: function(file, done) {
            fileToBase64(file); 
            $('#cropbox').cropper('replace', $('#cropbox').attr('src'));
            $('.wrapper-crop-box').fadeIn();
            done();
        },
        init: function() {
            this.on("addedfile", function(file) {
                if (this.files[1]!=null){
                    this.removeFile(this.files[0]);
                }
            });
        }
    };

    $('#cropbox').cropper({
      aspectRatio: 1 / 1,
      resizable: false,
      guides: false,
      dragCrop: false,
      autoCropArea: 0.4,
      checkImageOrigin: false,
      preview: '.avatar'
    });
});

你可能不再需要它了,但我就把它留在这里:)

这有点棘手,我的解决方案可能在某种程度上 'hackish',但它有效,而且您不必在服务器上上传文件来调整大小。

我还在模态 window 中使用 cropper。我想强制用户在上传到服务器之前将图像裁剪到特定尺寸。

确认模态图像裁剪后立即上传。

// transform cropper dataURI output to a Blob which Dropzone accepts
function dataURItoBlob(dataURI) {
    var byteString = atob(dataURI.split(',')[1]);
    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }
    return new Blob([ab], { type: 'image/jpeg' });
}

// modal window template
var modalTemplate = '<div class="modal"><!-- bootstrap modal here --></div>';

// initialize dropzone
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone(
    "#my-dropzone-container",
    {
        autoProcessQueue: false,
        // ..your other parameters..
    }
);

// listen to thumbnail event
myDropzone.on('thumbnail', function (file) {
    // ignore files which were already cropped and re-rendered
    // to prevent infinite loop
    if (file.cropped) {
        return;
    }
    if (file.width < 800) {
        // validate width to prevent too small files to be uploaded
        // .. add some error message here
        return;
    }
    // cache filename to re-assign it to cropped file
    var cachedFilename = file.name;
    // remove not cropped file from dropzone (we will replace it later)
    myDropzone.removeFile(file);

    // dynamically create modals to allow multiple files processing
    var $cropperModal = $(modalTemplate);
    // 'Crop and Upload' button in a modal
    var $uploadCrop = $cropperModal.find('.crop-upload');

    var $img = $('<img />');
    // initialize FileReader which reads uploaded file
    var reader = new FileReader();
    reader.onloadend = function () {
        // add uploaded and read image to modal
        $cropperModal.find('.image-container').html($img);
        $img.attr('src', reader.result);

        // initialize cropper for uploaded image
        $img.cropper({
            aspectRatio: 16 / 9,
            autoCropArea: 1,
            movable: false,
            cropBoxResizable: true,
            minContainerWidth: 850
        });
    };
    // read uploaded file (triggers code above)
    reader.readAsDataURL(file);

    $cropperModal.modal('show');

    // listener for 'Crop and Upload' button in modal
    $uploadCrop.on('click', function() {
        // get cropped image data
        var blob = $img.cropper('getCroppedCanvas').toDataURL();
        // transform it to Blob object
        var newFile = dataURItoBlob(blob);
        // set 'cropped to true' (so that we don't get to that listener again)
        newFile.cropped = true;
        // assign original filename
        newFile.name = cachedFilename;

        // add cropped file to dropzone
        myDropzone.addFile(newFile);
        // upload cropped file with dropzone
        myDropzone.processQueue();
        $cropperModal.modal('hide');
    });
});

我在 angular.js 模块中使用 dropzone.js 和 cropper.js 完成了它。也许它可以帮助某人。

[http://pastebin.com/4miiWbyZ][1] - angularjs
[http://pastebin.com/1kBkvWt8][2] - dropzone.html
[http://pastebin.com/jmDdNWFf][3] - cropper.html

这是提供此功能的要点。

https://gist.github.com/maria-p/8633b51f629ea8dbd27e

// transform cropper dataURI output to a Blob which Dropzone accepts
function dataURItoBlob(dataURI) {
    var byteString = atob(dataURI.split(',')[1]);
    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }
    return new Blob([ab], { type: 'image/jpeg' });
}

// modal window template
var modalTemplate = '<div class="modal"><!-- bootstrap modal here --></div>';

// initialize dropzone
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone(
    "#my-dropzone-container",
    {
        autoProcessQueue: false,
        // ..your other parameters..
    }
);

// listen to thumbnail event
myDropzone.on('thumbnail', function (file) {
    // ignore files which were already cropped and re-rendered
    // to prevent infinite loop
    if (file.cropped) {
        return;
    }
    if (file.width < 800) {
        // validate width to prevent too small files to be uploaded
        // .. add some error message here
        return;
    }
    // cache filename to re-assign it to cropped file
    var cachedFilename = file.name;
    // remove not cropped file from dropzone (we will replace it later)
    myDropzone.removeFile(file);

    // dynamically create modals to allow multiple files processing
    var $cropperModal = $(modalTemplate);
    // 'Crop and Upload' button in a modal
    var $uploadCrop = $cropperModal.find('.crop-upload');

    var $img = $('<img />');
    // initialize FileReader which reads uploaded file
    var reader = new FileReader();
    reader.onloadend = function () {
        // add uploaded and read image to modal
        $cropperModal.find('.image-container').html($img);
        $img.attr('src', reader.result);

        // initialize cropper for uploaded image
        $img.cropper({
            aspectRatio: 16 / 9,
            autoCropArea: 1,
            movable: false,
            cropBoxResizable: true,
            minContainerWidth: 850
        });
    };
    // read uploaded file (triggers code above)
    reader.readAsDataURL(file);

    $cropperModal.modal('show');

    // listener for 'Crop and Upload' button in modal
    $uploadCrop.on('click', function() {
        // get cropped image data
        var blob = $img.cropper('getCroppedCanvas').toDataURL();
        // transform it to Blob object
        var newFile = dataURItoBlob(blob);
        // set 'cropped to true' (so that we don't get to that listener again)
        newFile.cropped = true;
        // assign original filename
        newFile.name = cachedFilename;

        // add cropped file to dropzone
        myDropzone.addFile(newFile);
        // upload cropped file with dropzone
        myDropzone.processQueue();
        $cropperModal.modal('hide');
    });
});

注意,我不是作者

对于不想或不能拥有 jQuery 依赖项的开发人员。

我最近写了一篇article on integrating Dropzone with Cropper.js,可能会有用。请参阅下面文章中的代码片段。

HTML

<div class="dropzone" id="myDropzone"></div>

JavaScript

Dropzone.options.myDropzone = {
    url: '/post',
    transformFile: function(file, done) {

        var myDropZone = this;

        // Create the image editor overlay
        var editor = document.createElement('div');
        editor.style.position = 'fixed';
        editor.style.left = 0;
        editor.style.right = 0;
        editor.style.top = 0;
        editor.style.bottom = 0;
        editor.style.zIndex = 9999;
        editor.style.backgroundColor = '#000';

        // Create the confirm button
        var confirm = document.createElement('button');
        confirm.style.position = 'absolute';
        confirm.style.left = '10px';
        confirm.style.top = '10px';
        confirm.style.zIndex = 9999;
        confirm.textContent = 'Confirm';
        confirm.addEventListener('click', function() {

            // Get the canvas with image data from Cropper.js
            var canvas = cropper.getCroppedCanvas({
                width: 256,
                height: 256
            });

            // Turn the canvas into a Blob (file object without a name)
            canvas.toBlob(function(blob) {

                // Update the image thumbnail with the new image data
                myDropZone.createThumbnail(
                    blob,
                    myDropZone.options.thumbnailWidth,
                    myDropZone.options.thumbnailHeight,
                    myDropZone.options.thumbnailMethod,
                    false, 
                    function(dataURL) {

                        // Update the Dropzone file thumbnail
                        myDropZone.emit('thumbnail', file, dataURL);

                        // Return modified file to dropzone
                        done(blob);
                    }
                );

            });

            // Remove the editor from view
            editor.parentNode.removeChild(editor);

        });
        editor.appendChild(confirm);

        // Load the image
        var image = new Image();
        image.src = URL.createObjectURL(file);
        editor.appendChild(image);

        // Append the editor to the page
        document.body.appendChild(editor);

        // Create Cropper.js and pass image
        var cropper = new Cropper(image, {
            aspectRatio: 1
        });

    }
};

可在此处找到集成代码的演示: https://codepen.io/rikschennink/pen/PXQNGp?editors=0010