uniapp使用canvas压缩图片

本文介绍了一种使用canvas进行图片压缩并转换为Base64格式的方法,适用于微信小程序、H5及App端。文章详细讲解了压缩逻辑、不同平台下的Base64转换实现,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:
按照比例压缩图片宽高(这里设置为1200px,图片宽或高其中超过1200px就进行压缩,可以自己设置值),压缩后的图片转成base64格式,一次性提交到后台

平台兼容说明
利用canvas压缩图片的方式兼容微信小程序H5App端。但图片转base64各端的实现是不一致的,需要注意的是,canvas压缩图片在H5端输出的图片格式就是base64,所以H5端无需进行转换

为了方便,这里用的是uView的Upload组件,组件文档参考Upload组件

<view class="compress">
	<form @submit="formSubmit">
		<u-upload ref="Upload" :auto-upload="false" :show-progress="false" width="200" height="200"></u-upload>
		<view class="uni-btn-v u-m-t-80"><button form-type="submit" class="submit">提交</button></view>
	</form>
	<canvas class="canvas" :style="{ width: `${cWidth}px`, height: `${cHeight}px` }" canvas-id="myCanvas"></canvas>
</view>
export default {
	data() {
		return {
			cWidth: 200, //设置canvas画布的宽
			cHeight: 200 //设置canvas画布的高
		}
	}
}

这里采用手动上传的方式,通过ref获取上传图片列表

methods: {
	//获取图片信息
	async formSubmit() {
		let imgList = [];
		this.list = this.$refs.Upload.lists; //获取图片列表
		for (let i = 0; i < this.list.length; i++) {
			let item = this.list[i];
			let img = await this.imageToBase64(item); //调用图片转base64的方法
			imgList.push(img);
		}
	}
}

微信小程序使用官方提供的的uni.getFileSystemManager(仅适用于小程序端)获取文件管理器 ,具体文档见uni.getFileSystemManager。再通过FileSystemManager.readFile读取本地文件内容,具体文档见FileSystemManager.readFile

App端采用plus.io.resolveLocalFileSystemURL(),具体文档详见 App扩展规范 HTML5 Plus

		//图片转base64
		imageToBase64(item) {
			return new Promise(async (resolve, reject) => {
				let res = await this.compressImage(item); // 调用压缩图片的方法,先压缩图片,再转base64
				//#ifdef MP-WEIXIN
				uni.getFileSystemManager().readFile({
					filePath: res.tempFilePath,
					encoding: 'base64',
					success: function(data) {
						resolve(data.data);
					}
				});
				//#endif

				//#ifdef H5
				let url = res.tempFilePath.replace(/^data:image\/\w+;base64,/, '');
				resolve(url);
				//#endif

				// #ifdef APP-PLUS
				plus.io.resolveLocalFileSystemURL(res.tempFilePath, function(entry) {
					entry.file(function(file) {
						let fileReader = new plus.io.FileReader();
						fileReader.readAsDataURL(file);
						fileReader.onloadend = function(evt) {
							let url = evt.target.result.replace('/^data:image\/\w+;base64,/', '');
							resolve(url);
						};
					});
				});
				// #endif
			});
		}

上面调用了compressImage方法压缩图片,下面就来看看如何压缩图片

	//压缩图片
	compressImage(item) {
		return new Promise(async (resolve, reject) => {
			let info = await this.getImageInfo(item.url); // 获取图片信息,获取到图片的宽高,当图片宽度或高度其中一个超过设置的最大值时,就把对应的宽高设置成最大值(这里设置为1200),然后另一边按等比例进行缩放
			let maxWidth = 1200;
			let maxHeight = 1200;
			let canvasWidth = info.width; //图片实际宽度
			let canvasHeight = info.height; //图片实际高度
			let scale = 1;

			if (canvasWidth > maxWidth) {
				scale = canvasWidth / maxWidth;
				canvasWidth = maxWidth;
				canvasHeight = Math.floor(canvasHeight / scale);
			}

			if (canvasHeight > maxHeight) {
				scale = canvasHeight / maxHeight;
				canvasHeight = maxHeight;
				canvasWidth = Math.floor(canvasWidth / scale);
			}

			this.cWidth = canvasWidth;
			this.cHeight = canvasHeight;

			// 绘制canvas
			let ctx = uni.createCanvasContext('myCanvas', this);
			//清除画布
			ctx.clearRect(0, 0, canvasWidth, canvasHeight);
			//绘制图片
			ctx.drawImage(info.path, 0, 0, canvasWidth, canvasHeight);
			ctx.draw(
				false,
				setTimeout(() => {
					//导出图片路径
					uni.canvasToTempFilePath({
						canvasId: 'myCanvas',  // 画布标识:canvas-id
						width: canvasWidth,
						height: canvasHeight,
						destWidth: canvasWidth, //输出图片宽度
						destHeight: canvasHeight, //输出图片高度
						fileType: 'jpg', //目标文件的类型
						success: res => {
							resolve(res);
						},
						fail: err => {
							reject(err);
							console.log('err:', err);
						}
					});
				})
			);
		});
	},
	//获取图片信息
	getImageInfo(url) {
		return new Promise((resolve, reject) => {
			uni.getImageInfo({
				src: url,
				success: info => {
					resolve(info);
				},
				fail: err => {
					console.log('err:', err);
				}
			});
		});
	},

至此,前端压缩图片就完成啦~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值