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

使用Dropzone的resizeWidth选项后图片旋转的问题及解决办法

解决Dropzone v5图片缩放后的旋转问题

手机拍摄的JPG图片会携带EXIF方向元数据,记录拍摄时的设备摆放角度,但Dropzone默认的resize功能不会读取该信息,直接按原始像素尺寸缩放,导致最终上传的图片方向错误。

以下是具体解决方法:

步骤1:引入EXIF处理库

先准备exif-js库(自行下载后放入项目),在Dropzone脚本之前引入该库,用于读取图片的EXIF方向信息。

步骤2:自定义Dropzone的resize函数

替换原配置中的resizeWidth选项,改用自定义resize函数,在缩放前根据EXIF方向调整图片的绘制角度:

Dropzone.autoDiscover = false;
var myDropzone = new Dropzone("div#myDrop", {
    paramName: "files",
    addRemoveLinks: true,
    uploadMultiple: true,
    autoProcessQueue: false,
    parallelUploads: 50,
    maxFilesize: 100, // MB
    acceptedFiles: ".png, .jpeg, .jpg, .gif",
    resizeQuality: 0.8,
    url: "{{ path('property_upload_photos', {'token': property.token}) }}",
    // 自定义resize函数处理EXIF方向
    resize: function(file) {
        return new Promise((resolve) => {
            // 仅处理JPG/JPEG格式,其他格式用默认逻辑
            if (!file.type.match(/image\/jpeg/)) {
                const defaultResize = Dropzone.prototype.resize;
                return resolve(defaultResize.call(this, file));
            }

            // 读取图片的EXIF方向数据
            EXIF.getData(file, function() {
                const orientation = EXIF.getTag(this, "Orientation");
                const img = new Image();
                img.src = URL.createObjectURL(file);

                img.onload = function() {
                    const canvas = document.createElement("canvas");
                    const ctx = canvas.getContext("2d");
                    let width = img.width;
                    let height = img.height;
                    let scaleFactor = 1;

                    // 计算缩放比例,确保宽度不超过1000px
                    if (width > 1000) {
                        scaleFactor = 1000 / width;
                    }

                    // 根据EXIF方向调整画布和绘制逻辑
                    switch (orientation) {
                        case 2: // 水平翻转
                            canvas.width = width * scaleFactor;
                            canvas.height = height * scaleFactor;
                            ctx.scale(-scaleFactor, scaleFactor);
                            ctx.drawImage(img, -width, 0);
                            break;
                        case 3: // 旋转180度
                            canvas.width = width * scaleFactor;
                            canvas.height = height * scaleFactor;
                            ctx.rotate(Math.PI);
                            ctx.drawImage(img, -width * scaleFactor, -height * scaleFactor);
                            break;
                        case 4: // 垂直翻转
                            canvas.width = width * scaleFactor;
                            canvas.height = height * scaleFactor;
                            ctx.scale(scaleFactor, -scaleFactor);
                            ctx.drawImage(img, 0, -height);
                            break;
                        case 5: // 顺时针90度+水平翻转
                            canvas.width = height * scaleFactor;
                            canvas.height = width * scaleFactor;
                            ctx.rotate(0.5 * Math.PI);
                            ctx.scale(-scaleFactor, scaleFactor);
                            ctx.drawImage(img, -height, 0);
                            break;
                        case 6: // 顺时针90度
                            canvas.width = height * scaleFactor;
                            canvas.height = width * scaleFactor;
                            ctx.rotate(0.5 * Math.PI);
                            ctx.drawImage(img, 0, -width * scaleFactor);
                            break;
                        case 7: // 逆时针90度+水平翻转
                            canvas.width = height * scaleFactor;
                            canvas.height = width * scaleFactor;
                            ctx.rotate(-0.5 * Math.PI);
                            ctx.scale(-scaleFactor, scaleFactor);
                            ctx.drawImage(img, -height * scaleFactor, width * scaleFactor);
                            break;
                        case 8: // 逆时针90度
                            canvas.width = height * scaleFactor;
                            canvas.height = width * scaleFactor;
                            ctx.rotate(-0.5 * Math.PI);
                            ctx.drawImage(img, -height * scaleFactor, 0);
                            break;
                        default: // 正常方向
                            canvas.width = width * scaleFactor;
                            canvas.height = height * scaleFactor;
                            ctx.drawImage(img, 0, 0, width * scaleFactor, height * scaleFactor);
                    }

                    // 将处理后的画布转为Blob,返回给Dropzone
                    canvas.toBlob(function(blob) {
                        resolve({
                            src: URL.createObjectURL(blob),
                            blob: blob,
                            width: canvas.width,
                            height: canvas.height
                        });
                    }, file.type, 0.8);
                };
            });
        });
    }
});

$("#add_file").on("click",function (){
    myDropzone.processQueue();
});

关键说明

  • 仅针对JPG/JPEG格式处理:PNG、GIF等格式通常不包含EXIF方向数据,直接使用Dropzone默认的resize逻辑。
  • 覆盖所有方向场景:代码中处理了EXIF定义的8种图片方向,确保各种手机拍摄角度的图片都能正确显示。
  • 保持缩放逻辑:保留了原需求中宽度不超过1000px的缩放规则,同时保证图片方向正确。

内容的提问来源于stack exchange,提问作者hous

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 02:59:54