压缩图片js方法,新建imgPress.js
/**
* 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);
});
}
// 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 页面调用
import {compressH5,binarySearchCompress} from './imgPress'
方法引入,注意:uploadCompressedImage方法上传里七牛云上传就需要七牛云token,里面处理图片可以根据需求修改,如果是上传后台,可以用后台方法上传。
// 上传图片
upload(key){
const that = this
uni.chooseImage({
count: 1, //默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: res => {
console.log(res)
// 获取文件的临时路径
let avatar = res.tempFilePaths[0];
let files = res.tempFiles[0]
const fileSize = files.size;
console.log('fileSize',fileSize)
if(fileSize/1024/1024 >20){
return that.$tools.toast('请上传20M以内的图片')
}
uni.showLoading({
mask: true,
});
// 判断图片大小是否超过200KB
if (fileSize > 200 * 1024) {
//#ifdef H5
//h5压缩图片
const targetSizeKB = 150; // 设置目标文件大小,单位为KB,根据需求调整
compressH5(files,targetSizeKB).then(file => {
console.log('file 222 = ', file)
that.uploadCompressedImage(file,key);
}).catch(err => {
console.log('catch', err)
uni.hideLoading();
})
//#endif
//#ifdef APP-PLUS || MP-WEIXIN
// 如果超过200KB,进行压缩
// 初始压缩质量范围
const lowQuality = 1;
const highQuality = 100;
binarySearchCompress(files, targetSize, lowQuality, highQuality, (compressedFilePath) => {
console.log("压缩成功,压缩后图片路径:", compressedFilePath);
that.uploadCompressedImage(file,key);
}, (err) => {
console.error("压缩失败:", err);
uni.hideLoading();
})
//#endif
} else {
// 如果未超过200KB,直接上传原图
that.uploadCompressedImage(avatar,key);
}
},
fail: (error) => {
console.log(error);
that.$tools.toast('上传图片接口调用失败')
uni.hideLoading();
},
})
},
// 压缩上传
uploadCompressedImage(avatar,key){
const that = this
// let avatar = res.tempFiles;
let KeySrc = key+'Src'
console.log(key,avatar)
that[KeySrc] = avatar;
that.$set(that,KeySrc,avatar)
let now_time = new Date().getTime();
uni.uploadFile({
url: 'https://up-z2.qiniup.com',
filePath: avatar,
name: 'file',
formData: {
// 'key': now_time,
'token': that.qiniu.qiniu_token,
},
success: (uploadFileRes) => {
let uploadImgUrl = JSON.parse(uploadFileRes.data).key;
// let backUrl = that.qiniu.qiniu_domain + '/' +uploadImgUrl;
let backUrl = uploadImgUrl;
that[key] = backUrl;
that.$set(that,key,backUrl)
console.log(key,this[key])
uni.hideLoading();
},
fail: (error) => {
console.log(error);
uni.hideLoading();
},
complete: () => {
setTimeout(function() {
uni.hideLoading();
}, 250);
},
});
},