You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:10:14