uniapp图片压缩

最近在开发中有需求需要压缩图片,这里我就记录下压缩方法以及遇到的坑。

首先需要用到canvas,这里我是写成一个组件,在需要用到的地方引入就好。

由于这里跨文件了,所以这里用vuex将this记录下来。

<template>
	<canvas canvas-id="compression-image" style="position: fixed; left: -99999px; top: -99999px; width: 1000px; height: 1000px;" />
</template>
 
<script>
	export default {
		name: "compression-image",
		mounted() {
			this.$store.commit("setCompressionImageThis", this);
		},
		beforeDestroy() {
			this.$store.commit("setCompressionImageThis", null);
		},
	}
</script>

vuex中的代码如下:

/** 存放compressionImage组件的一些数据 */
export default {
	state: {
		// compressionImage组件的this
		compressionImageThis: null,
	},
	getters: {
		/** 获取compressionImage组件的实例 */
		getCompressionImageThis: state => {
			return state.compressionImageThis;
		}
	},
	mutations: {
		/** 设置compressionImage组件的实例 */
		setCompressionImageThis: (state, data) => {
			state.compressionImageThis = data;
		}
	}
}

引入之后,页面上就有canvas了,之后就在js代码部分进行图片压缩,如下:


// 这边引入vuex对象 - 获取到之前存的this
import store from "@/store/index.js";


/**
 * 处理对图片进行压缩
 * 配合compression-image组件一起使用,在需要用到的页面引入compression-image组件就能对图片进行压缩
 * @param {string} url 图片路径
 * @param {number} size 文件大小
 * @param {string} fileType 文件类型
 * */
export const getCompressionImage = (url, size = 0, fileType = 'jpg') => {
	return new Promise(async resolve => {
		// 获取this对象
		const _this = store.getters.getCompressionImageThis;
		// 判断this是否存在
		if(!_this) {
			resolve(url);
		}
		// 默认判断的size
		const defaultSize = 1024 * 1024;
		// 画布的尺寸
		const canvasWidth = 1000;
		const canvasHeight = 1000;
		// 获取canvas上下文对象
		const context = uni.createCanvasContext("compression-image", _this);
		// 清空画布 - 这边的 清空尺寸 来自于compression-image组件画布的大小
		context.clearRect(0, 0, canvasWidth, canvasHeight);
		
		// 图片缩放的比例
		let ratio = 1;
		// 判断是否需要缩放
		if(size > defaultSize) {
			ratio = Math.sqrt(size / defaultSize);
		}
		
		// 获取图片的信息
		uni.getImageInfo({
			src: url,
			success: res => {
				let { path, width, height } = res;
				
				width = width / ratio;
				height = height / ratio;
				
				// 判断缩放后的是否超出画布
				if(width > canvasWidth || height > canvasHeight) {
					if(width > height) {
						ratio = width / canvasWidth;
					}
					else {
						ratio = height / canvasHeight;
					}
					width = width / ratio;
					height = height / ratio;
				}
				
				// 将图片绘制到canvas中
				context.drawImage(path, 0, 0, width, height);
				
				// 进行绘制...
				context.draw(false, () => {
					// 保存图片为临时路径
					uni.canvasToTempFilePath({
						canvasId: "compression-image",
						x: 0,
						y: 0,
						width: width,
						height: height,
						destWidth: width,
						destHeight: height,
						fileType,
						success: res => {
							resolve(res.tempFilePath);
						},
						fail: err => {
							resolve(url);
						}
					}, _this);
				});
			},
			fail: () => {
				resolve(url);
			},
		});
	});
}

最后使用😃

// HTML部分使用组件
<compression-image />

<script>
    // JS部分 - 这里随便举例子
    const test = async () {
        const url = await getCompressionImage("这里传入需要压缩图片的路径", "这里传入图片大小", "这里传入图片的类型");

        console.log(url, "这里就是压缩后的图片路径,传给后端就好啦!");
    }
</script>

遇到的问题:

真机调试的时候绘制图片是白屏 ----- 解决办法就是调整canvas画布的宽高,canvas画布不能太大。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值