ここでやりたいのは、Dropzone.jsがドロップされた画像をサーバーに送信する前に、ユーザーが画像をトリミングできるように、cropper.js(fengyuanchenスクリプト)でモーダルが表示され、画像がトリミングされたら、Dropzone.jsで送信します。サーバーに。
したがって、#cropboxの画像srcを関数fileToBase64で変更し、クロッパーの画像を関数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'
});
});
あなたはおそらくもうそれを必要としないでしょう、しかし私はそれをここに残しておきます:)
それは少しトリッキーで、私の解決策はおそらく「ハック」ですが、それは機能し、サイズを変更するためにサーバーにファイルをアップロードする必要はありません。
モーダルウィンドウでもクロッパーを使用しています。サーバーにアップロードする前に、ユーザーに画像を特定のサイズにトリミングするように強制したかったのです。
モーダル画像のトリミングを確認すると、すぐにアップロードされます。
// 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');
});
});
これがこの機能を提供する要点です。
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の依存関係を望まない、または持つことができない開発者向け。
私は最近 Dropzoneと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=001