当前位置: 首页 > article >正文

【UNIAPP】uniapp版图片压缩工具

二次封装的uniapp版本图片压缩、上传工具,支持全端(H5、小程序、APP)

  • 新建文件:file-util.js 
class FileUtil {
	/**
	 * [文件上传]
	 * @param  {[object]} fileObj    [图片地址]
	 * @param  {[object]} formData   [参数]
	 * @param  {[string]} url        [上传地址]
	 * @param  {[boolean]} compress  [是否压缩]
	 * @return {[Promise]}         [description]
	 */
	async uploadFile(fileObj, formData = {}, url, compress = true) {
		if (!fileObj) {
			return uni.showToast({
				title: '找不到文件~'
			});
		}

		setTimeout(() => {
			uni.showLoading({
				title: '上传中...',
				mask: true,
			})
		}, 500)

		let file = fileObj;
		if (compress) {
			file = await this.compressImage(fileObj)
		}

		return this.upload(file, formData, url)
	}

	/**
	 * 
	 * @param {Object} fileObj [文件对象]
	 * @param {Object} imageWidth 图片宽度
	 */
	async compressImage(fileObj, imageWidth = 500) {
		let file = fileObj;
		//#ifndef H5
		file = await this.compressByMp(fileObj)
		//#endif

		//#ifdef H5
		file = await this.compressByH5(fileObj, imageWidth)
		//#endif
		return file
	}

	/**
	 * [压缩图片-小程序/APP]
	 * @param  {[type]} fileObj [description]
	 * @return {[type]}         [description]
	 */
	async compressByMp(fileObj) {
		return new Promise(resolve => {
			if (fileObj.size > 500000) {
				uni.compressImage({
					src: fileObj.path, // 图片路径
					quality: 60, // 压缩质量
					success(res) {
						let file = {
							name: fileObj.name,
							type: fileObj.type,
							size: fileObj.size,
							path: res.tempFilePath
						}
						resolve(file)
					},
					fail(error) {
						console.warn('图片压缩异常,使用原图', error)
						resolve(fileObj)
					}
				})
			} else {
				console.warn('500K以下不压缩')
				resolve(fileObj)
			}
		})
	}
	/**
	 * H5压缩
	 * @param {Object} fileObj 文件对象
	 * @param {Object} imageWidth 图片宽度
	 * @returns
	 */
	compressByH5(fileObj, imageWidth) {
		return new Promise(resolve => {
			try {
				uni.getImageInfo({
					src: fileObj.path,
					success: function(res) {
						let canvasWidth = res.width //图片原始长宽
						let canvasHeight = res.height;
						let base = canvasWidth / canvasHeight;
						if (canvasWidth > imageWidth) {
							canvasWidth = imageWidth;
							canvasHeight = Math.floor(canvasWidth / base);
						}
						let img = new Image();
						img.src = fileObj.path; // 要压缩的图片  
						let canvas = document.createElement('canvas');
						let ctx = canvas.getContext('2d');
						canvas.width = canvasWidth;
						canvas.height = canvasHeight;

						//  将图片画到canvas上面   使用Canvas压缩  
						ctx.drawImage(img, 0, 0, canvasWidth, canvasHeight);
						canvas.toBlob(function(fileSrc) {
							let imgSrc = window.URL.createObjectURL(fileSrc); //原生JS生成文件路径
							uni.downloadFile({
								url: imgSrc, //仅为示例,并非真实的资源
								success: (res) => {
									console.log('downloadFile', res)
									if (res.statusCode === 200) {
										let file = {
											name: fileObj.name,
											type: fileObj.type,
											size: fileObj.size,
											path: res.tempFilePath
										}
										resolve(file)
									} else {
										console.warn('图片压缩异常,使用原图', res)
										resolve(fileObj)
									}
								},
								fail(error) {
									console.warn('图片压缩异常,使用原图', error)
									resolve(fileObj)
								}
							})
						});
					}
				})
			} catch (e) {
				console.warn('图片压缩异常,使用原图', e)
				resolve(file)
			}
		})
	}
	/**
	 * 图片转base64 - H5
	 * @param {Object} file
	 * @param {Object} imageWidth
	 * @returns
	 */
	compresToBase64ForH5(file, imageWidth) {
		return new Promise((resolve, reject) => {
			try {
				uni.getImageInfo({
					src: file.path,
					success: function(res) {
						let canvasWidth = res.width //图片原始长宽
						let canvasHeight = res.height;
						let base = canvasWidth / canvasHeight;
						if (canvasWidth > imageWidth) {
							canvasWidth = imageWidth;
							canvasHeight = Math.floor(canvasWidth / base);
						}
						let img = new Image();
						img.src = file.path; // 要压缩的图片  
						let canvas = document.createElement('canvas');
						let ctx = canvas.getContext('2d');
						canvas.width = canvasWidth;
						canvas.height = canvasHeight;

						//  将图片画到canvas上面   使用Canvas压缩  
						ctx.drawImage(img, 0, 0, canvasWidth, canvasHeight);
						var ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase();
						var dataURL = canvas.toDataURL("image/" + ext);
						resolve(dataURL)
					}
				})
			} catch (e) {
				reject(e)
			}
		})
	}
	/**
	 * 上传到服务器 (响应报文按实际情况调整)
	 * @param {Object} file
	 * @param {Object} formData
	 * @param {Object} url
	 */
	upload(file, formData, url) {
		console.log(file)
		if (!formData) formData = {}
		return new Promise((resolve, reject) => {
			uni.uploadFile({
				url,
				filePath: file.path,
				formData,
				name: 'file',
				header: {
					"chartset": "utf-8",
					'X-Access-Token': "token",
					// "content-type":'application/x-www-form-urlencoded'
				},
				success(res) {
					let dataJson = JSON.parse(res.data)
					if (res.statusCode == 200) {
						// resolve(decodeURIComponent(data))
						if (dataJson.success) {
							resolve(dataJson.result)
						} else {
							let tip = '上传失败'
							if (dataJson && dataJson.message) tip = dataJson.message
							uni.showToast({
								title: tip
							})
							reject(dataJson)
						}
					} else {
						let tip = '上传失败'
						if (dataJson && dataJson.message) tip = dataJson.message
						uni.showToast({
							title: tip
						})
						reject(dataJson)
					}
				},
				fail(error) {
					let message = error.errMsg;
					if (message.indexOf('uploadFile:fail timeout') > -1) message = '上传超时,请尝试压缩图片'
					else if (message.indexOf('uploadFile:fail') > -1) message = '服务器或网络异常,信息提交失败!'
					else message = '上传失败'
					uni.showToast({
						title: message
					})
					reject(error)
				},
				complete(res) {
					console.log(res)
					setTimeout(() => {
						uni.hideLoading();
					}, 500)
				}
			})
		})
	}
}

export default new FileUtil()
  •  使用:
import FileUtil from '@/utils/file-util'

FileUtil.upload(fileObj)


http://www.kler.cn/a/401176.html

相关文章:

  • 【插件】重复执行 pytest-repeat
  • Misc_01转二维码(不是二进制)
  • 理解 Python 中的 __getitem__ 方法:在自定义类中启用索引和切片操作
  • ASP.NET Core Webapi 返回数据的三种方式
  • WebSocket实战,后台修改订单状态,前台实现数据变更,提供前端和后端多种语言
  • 剧本杀门店预约小程序,解锁沉浸式推理体验
  • UE5 材质里面画圆锯齿严重的问题
  • 深入理解电子邮件安全:SPF、DKIM 和 DMARC 完全指南
  • 【.net core】【sqlsugar】字符串拼接+内容去重
  • Linux 安装 jdk8
  • 嵌入式工作经验积累
  • 网络抓包工具tcpdump 在海思平台上的编译使用
  • Leetcode打卡:最少翻转次数使二进制矩阵回文II
  • 编程小记1 throw new RuntimeException(“错误信息“);
  • 跨平台WPF框架Avalonia教程 六
  • 缓存工具类编写
  • docker run怎么设置 entry point sleep?
  • 【AIGC】ChatGPT提示词Prompt解析:文章创作大师
  • EMNLP 2024 | 大语言模型的内部知识机理
  • 高效管理 SSH 免密码登录:多客户端与多服务器实践指南20241118
  • 鲸鱼机器人和乐高机器人的比较
  • 搭建vue-electron项目
  • 自动驾驶系统研发系列—智能驾驶核心功能:IHC如何提升夜间驾驶体验?
  • 数造科技亮相第26届高交会并接受媒体采访,以数据智能赋能未来
  • Oracle收缩表空间的简单方法
  • 每日OJ题_牛客_dd爱旋转_模拟_C++_Java