赞
踩
项目是用uniapp开发的,当时只是做App端,后来项目扩展到H5端, uniapp框架可以跨平台所以移动端和H5使用的是一套代码
上传头像的时候要求图片的大小在2MB一下,所以要压缩图片,App端当时使用的是uni.compressImage(OBJECT)压缩的(详情见:https://uniapp.dcloud.net.cn/api/media/image.html#compressimage 但是H5不兼容;
先搞定H5的压缩吧!网上一搜一大把
/** * H5压缩 二分查找算法来找到一个合适的图像质量系数,使得压缩后的图片文件大小接近于目标大小 * @param {Object} imgSrc 图片url * @param {Object} callback 回调设置返回值 * */ export function compressH5(fileItem, targetSizeKB, initialQuality = 1.0) { const maxQuality = 1.0; const minQuality = 0.0; const tolerance = 0.01; // 根据需要调整公差 return new Promise((resolve, reject) => { const binarySearch = (min, max) => { const midQuality = (min + max) / 2; const reader = new FileReader(); reader.readAsDataURL(fileItem); reader.onload = function () { const img = new Image(); img.src = this.result; img.onload = function () { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = img.width; canvas.height = img.height; ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // 使用异步的 toBlob 方法 canvas.toBlob(async (blob) => { const fileSizeKB = blob.size / 1024; if (Math.abs(fileSizeKB - targetSizeKB) < tolerance || max - min < tolerance) { // 当前质量足够接近目标大小,使用当前质量解析 resolve(URL.createObjectURL(blob)); } else if (fileSizeKB > targetSizeKB) { // 如果文件大小太大,降低质量,继续二分查找 binarySearch(min, midQuality); } else { // 如果文件大小太小,增加质量,继续二分查找 binarySearch(midQuality, max); } }, 'image/jpeg', midQuality); }; }; reader.onerror = function (error) { reject(error); }; }; // 开始二分查找 binarySearch(minQuality, maxQuality); }); }
调用方法
chooseImg1() { uni.chooseImage({ count: 1, //默认9 sizeType:['compressed'], success: (chooseImageRes) => { const tempFilePaths = chooseImageRes.tempFilePaths; const filePath = tempFilePaths[0]; // 获取图片文件大小 uni.getFileInfo({ filePath: filePath, success: (fileInfo) => { const fileSize = fileInfo.size; // 图片文件大小,单位为B // 判断图片大小是否超过200KB if (fileSize > 200 * 1024) { //#ifdef H5 //h5压缩图片 const targetSizeKB = 150; // 设置目标文件大小,单位为KB,根据需求调整 compressH5(chooseImageRes.tempFiles[0],targetSizeKB).then(file => { console.log('file 222 = ', file) this.uploadCompressedImage(file); }).catch(err => { console.log('catch', err) }) //#endif //#ifdef APP-PLUS || MP-WEIXIN // 如果超过200KB,进行压缩 uni.compressImage({ src: filePath, quality: 10, // 设置压缩质量(0-100)- 根据需求进行调整 success: (compressRes) => { // 压缩成功后的逻辑 this.uploadCompressedImage(compressRes.tempFilePath); }, fail: (err) => { console.error('压缩图片失败:', err); uni.showToast({ title: '压缩图片失败,请重试', icon: 'none' }); } }); //#endif } else { // 如果未超过200KB,直接上传原图 this.uploadCompressedImage(filePath); } }, fail: (err) => { console.error('获取文件信息失败:', err); uni.showToast({ title: '获取文件信息失败,请重试', icon: 'none' }); } }); }, fail: (err) => { console.error('选择图片失败:', err); uni.showToast({ title: '选择图片失败,请重试', icon: 'none' }); } }); },
uploadCompressedImage(filePath) { uni.uploadFile({ url: `${this.$VUE_APP_API_URL}/common/image/image/upload/faceImg`, filePath: filePath, name: 'file', header: { 'Authorization': uni.getStorageSync('X-Token'), // 修改为你的访问令牌 }, success: (res) => { uni.hideLoading(); // 隐藏 loading if (res.statusCode === 200) { console.log('上传成功:', res.data); const responseData = JSON.parse(res.data); // 解析返回的数据 console.log(responseData,'responseData') // 处理上传成功后的逻辑 if(responseData.code==200){ this.contractImage1 = responseData.data uni.setStorageSync('faceUrl',this.contractImage1) }else{ uni.$u.toast(responseData.msg); } } else { console.error('上传失败', res.statusCode); uni.showToast({ title: res.msg, // 自定义错误信息 icon: 'none' }); } }, fail: (err) => { console.error('上传失败:', err); uni.showToast({ title: '上传失败,请重试', icon: 'none' }); } }); },
即能兼容h5也能兼容微信小程序和各个app
微信小程序图片压缩再次用二分查找压缩质量
// 压缩图片 export function compressImage(filePath, quality, successCallback, errorCallback) { uni.compressImage({ src: filePath, quality: quality, success: (res) => { successCallback(res.tempFilePath); }, fail: (err) => { errorCallback(err); } }); } // 二分查找压缩质量 export function binarySearchCompress(filePath, targetSize, low, high, successCallback, errorCallback) { if (low > high) { errorCallback("无法达到目标大小"); return; } const mid = Math.floor((low + high) / 2); compressImage(filePath, mid, (tempFilePath) => { uni.getFileInfo({ filePath: tempFilePath, success: (res) => { const currentSize = res.size; if (currentSize <= targetSize) { successCallback(tempFilePath); } else { // 递归调整压缩质量 binarySearchCompress(filePath, targetSize, low, mid - 1, successCallback, errorCallback); } }, fail: (err) => { errorCallback(err); } }); }, (err) => { errorCallback(err); }); }
vue文件引用
//#ifdef APP-PLUS || MP-WEIXIN // 如果超过200KB,进行压缩 const tempFilePath = chooseImageRes.tempFilePaths[0]; const targetSizeKB = 200; // 将目标大小转换为字节数 const targetSize = targetSizeKB * 1024; // 初始压缩质量范围 const lowQuality = 1; const highQuality = 100; binarySearchCompress(tempFilePath, targetSize, lowQuality, highQuality, (compressedFilePath) => { console.log("压缩成功,压缩后图片路径:", compressedFilePath); this.uploadCompressedImage(compressedFilePath); }, (err) => { console.error("压缩失败:", err); }) //#endif
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。