壓縮圖片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 = thisuni.chooseImage({count: 1, //默認9sizeType: ['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,});// 判斷圖片大小是否超過200KBif (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);},});},