移动端——Uni-app 使用 Cavans 压缩图片插件

等比例压缩图片 可指定图片宽高,兼容 H5 和 小程序

使用(引入组件,调用组件内 compress 方法)

<compress ref="compress" />

import compress from '@/components/compress.vue'

components: { compress }

// 在需要压缩时调用
uni.chooseImage({
	success: (chooseImageRes) => {
		const tempFilePaths = chooseImageRes.tempFilePaths;
		// compress
		const compressParams = {
			src: tempFilePaths[0] // 必选: 要压缩的图片地址
		}
		this.$refs.compress.compress(compressParams).then(filePath => {
			uni.uploadFile({
				url: baseUrl + '/upload',
				filePath: filePath,
				name: 'file',
				success: (uploadFileRes) => {}
			})
		})
	}
})

参数说明

key是否必选default说明
src必选-要压缩的图片地址
maxSize可选900最大尺寸
minSize可选640最小尺寸
fileType可选‘jpg’压缩后文件类型
quality可选0.7压缩质量

组件源码

<template>
	<view class="compress">
		<canvas :style="{ width: canvasSize.width,height: canvasSize.height}" canvas-id="myCanvas"></canvas>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				canvasSize: {
					width: '0px',
					height: '0px'
				}
			}
		},
		methods: {
			// 压缩
			compress(params) {
				return new Promise(async (resolve, reject) => {
					// 等待图片信息
					let info = await this.getImageInfo(params.src).then(info=>info).catch(err=>err);
					
					if(!info){
						reject('获取图片信息异常');
						return;
					}
					
					// 设置最大 & 最小 尺寸
					const maxSize = params.maxSize || 900;
					const minSize = params.minSize || 640;
					
					// 当前图片尺寸
					let {width,height} = info;
					
					// 非 H5 平台进行最小尺寸校验
					// #ifndef H5
					if(width <= minSize && height <= minSize){
						resolve(params.src);
						return;
					}
					// #endif
					
					// 最大尺寸计算
					if (width > maxSize || height > maxSize) {
						if (width > height) {
							height = Math.floor(height / (width / maxSize));
							width = maxSize;
						} else {
							width = Math.floor(width / (height / maxSize));
							height = maxSize;
						}
					}
					// 设置画布尺寸
					this.$set(this,"canvasSize",{
						width: `${width}rpx`,
						height: `${height}rpx`
					});
					
					// Vue.nextTick 回调在 App 有异常,则使用 setTimeout 等待DOM更新
					setTimeout(() => {
						const ctx = uni.createCanvasContext('myCanvas', this);
						ctx.clearRect(0,0,width, height)
						ctx.drawImage(info.path, 0, 0, uni.upx2px(width), uni.upx2px(height));
						ctx.draw(false, () => {
							uni.canvasToTempFilePath({
								x: 0,
								y: 0,
								width: uni.upx2px(width),
								height: uni.upx2px(height),
								destWidth: width,
								destHeight: height,
								canvasId: 'myCanvas',
								fileType: params.fileType || 'jpg',
								quality: params.quality || 0.7,
								success: (res) => {
									let resultPath = res.tempFilePath
									// 在H5平台下,tempFilePath 为 base64 需转换为 path
									// #ifdef H5
									const base64Code = this.dataURLtoBlob(resultPath)
									resultPath = URL.createObjectURL(base64Code)
									// #endif
									resolve(resultPath);
								},
								fail:(err)=>{
									console.log('fail', err)
									reject(null);
								}
							},this);
						});
					}, 300);
				});
			},
			dataURLtoBlob(dataurl) {
				var arr = dataurl.split(','),
					mime = arr[0].match(/:(.*?);/)[1],
					bstr = atob(arr[1]),
					n = bstr.length,
					u8arr = new Uint8Array(n) //8位无符号整数,长度1个字节
				while (n--) {
					u8arr[n] = bstr.charCodeAt(n)
				}
				return new Blob([u8arr], {
					type: mime,
				})
			},
			// 获取图片信息
			getImageInfo(src){
				return new Promise((resolve, reject)=>{
					uni.getImageInfo({
						src,
						success: (info)=> {
							resolve(info);
						},
						fail: () => {
							reject(null);
						}
					});
				});
			}
		}
	}
</script>

<style scoped>
	.compress{
		position: fixed;
		width: 12px;
		height: 12px;
		overflow: hidden;
		top: -99999px;
		left: 0;
	}
</style>


码字不易,觉得有帮助的小伙伴点个赞支持下~


在这里插入图片描述

扫描上方二维码关注我的订阅号~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张兴华(MarsXH.Chang)

喜欢的可以请作者喝杯咖啡~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值