如何在Dropzone.js上传图片前集成Cropper.js实现裁剪功能
集成Dropzone.js与Cropper.js实现上传前图片裁剪
我们可以通过拦截Dropzone的文件添加流程,在文件进入上传队列前触发Cropper裁剪操作,完成后将裁剪后的文件替换原文件加入队列。以下是适配你现有代码的完整实现:
修改后的HTML
添加裁剪用的遮罩层容器(无需Bootstrap):
<div class="dropzone dz-clickable" id="myDrop"> <div class="dz-default dz-message" data-dz-message=""> <span>No Photo Selected</span> </div> </div> <div id="add_file">POST</div> <!-- 裁剪模态框 --> <div id="crop-modal" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.8); z-index:9999; align-items:center; justify-content:center;"> <div style="max-width:80%; max-height:80%; position:relative;"> <img id="crop-image" style="max-width:100%; max-height:100%; border:2px solid white;"> <button id="confirm-crop" style="position:absolute; bottom:20px; right:20px; padding:10px 20px; background:#2ecc71; color:white; border:none; cursor:pointer; border-radius:4px; font-size:16px;">确认裁剪</button> <button id="cancel-crop" style="position:absolute; bottom:20px; left:20px; padding:10px 20px; background:#e74c3c; color:white; border:none; cursor:pointer; border-radius:4px; font-size:16px;">取消</button> </div> </div>
修改后的JavaScript
核心逻辑是拦截Dropzone的文件添加事件,触发Cropper裁剪后替换队列文件:
// 全局变量存储当前待裁剪的文件和Cropper实例 let currentDropzoneFile = null; let cropperInstance = null; //Dropzone script Dropzone.autoDiscover = false; var myDropzone = new Dropzone("div#myDrop", { paramName: "__files", // 文件传输参数名 addRemoveLinks: true, uploadMultiple: true, withCredentials: true, autoProcessQueue: false, parallelUploads: 5, maxFiles: 5, maxFilesize: 20, // MB acceptedFiles: ".png, .jpeg, .jpg, .gif, .JPG, .jfif", url: "sdk/process-upload.php", capture: "camera", init: function () { const dropzone = this; // 拦截文件添加事件,触发裁剪流程 this.on('addedfile', function(file) { // 移除Dropzone自动生成的预览图,后续添加裁剪后的文件 dropzone.removeFile(file); currentDropzoneFile = file; // 读取文件为DataURL,加载到Cropper容器 const reader = new FileReader(); reader.onload = function(e) { const cropImage = document.getElementById('crop-image'); cropImage.src = e.target.result; // 销毁旧的Cropper实例,初始化新实例(设置固定裁剪尺寸800x600,可自行修改) if (cropperInstance) cropperInstance.destroy(); cropperInstance = new Cropper(cropImage, { aspectRatio: 800/600, // 裁剪比例与目标尺寸一致 viewMode: 1, autoCropArea: 1, responsive: true }); // 显示裁剪模态框 document.getElementById('crop-modal').style.display = 'flex'; }; reader.readAsDataURL(file); }); // 保留原有附加数据逻辑 this.on('sending', function(file, xhr, formData) { var l = document.getElementById("locationval").value; formData.append('location', l); var x = document.getElementById("postmaker").innerText; formData.append('pdata', x); }); } }); // 确认裁剪按钮事件 document.getElementById('confirm-crop').addEventListener('click', function() { if (!cropperInstance || !currentDropzoneFile) return; // 获取裁剪后的Blob对象 cropperInstance.getCroppedCanvas({ width: 800, // 最终裁剪图片宽度 height: 600 // 最终裁剪图片高度 }).toBlob(function(blob) { // 将Blob转为File对象,保留原文件名和类型 const croppedFile = new File([blob], currentDropzoneFile.name, { type: currentDropzoneFile.type }); // 将裁剪后的文件添加到Dropzone队列 myDropzone.addFile(croppedFile); // 清理资源并关闭模态框 cropperInstance.destroy(); document.getElementById('crop-modal').style.display = 'none'; currentDropzoneFile = null; }, currentDropzoneFile.type); }); // 取消裁剪按钮事件 document.getElementById('cancel-crop').addEventListener('click', function() { if (cropperInstance) cropperInstance.destroy(); document.getElementById('crop-modal').style.display = 'none'; currentDropzoneFile = null; }); /* 保留原有事件逻辑 */ myDropzone.on("success", function(file, message){ $("#msg").html(message); //setTimeout(function(){window.location.href="index.php"},800); }); myDropzone.on("error", function (data) { $("#msg").html('<div class="alert alert-danger">There is some thing wrong, Please try again!</div>'); }); myDropzone.on("complete", function(file) { myDropzone.removeFile(file); }); $("#add_file").on("click",function (){ myDropzone.processQueue(); });
关键说明
- 拦截文件添加:通过
addedfile事件跳过Dropzone默认的预览生成,转而触发裁剪流程。 - 固定尺寸裁剪:Cropper初始化时设置的
aspectRatio和getCroppedCanvas的宽高参数,确保所有上传图片统一尺寸,可根据需求修改数值。 - 文件替换:裁剪完成后将Blob转为与原文件同名的File对象,保证上传逻辑与原有代码兼容。
注意:确保你的页面已正确引入Cropper.js的脚本和样式文件。
内容的提问来源于stack exchange,提问作者Dr Amit Kumar Jha
相关产品推荐
相关产品推荐

