使用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
相关产品推荐
相关产品推荐

