uniapp realizes the small program to open the photo album or take pictures and upload pictures with a compatible H5 method


foreword

The applet uploads pictures, or takes pictures and uploads pictures, and comes with a method compatible with H5 uploading pictures and compressing pictures.


1. Support album selection and photo taking

It supports selecting albums and taking pictures. You can use the api provided by uniapp. Of course, you can also package the style you want by yourself. Here I directly use the method of uni. uni.chooseImageconfigurationsourceType: ['album', 'camera']

openSelectImage() {
    
    
	let tempList = []
	uni.chooseImage({
    
    
		sizeType: ['compressed'],
		sourceType: ['album', 'camera'],
		success: (res) => {
    
    
			if (res.tempFilePaths?.length > 0) {
    
    
				tempList = res.tempFilePaths
				// #ifdef MP
				this.recursionCompressMP(tempList, (e) => {
    
    
					console.log('压缩后结果-----', e)
				})
				// #endif
				// #ifdef H5
				this.recursionCompressH5(tempList, (e) => {
    
    
					console.log('压缩后结果-----', e)
				})
				// #endif
			}
		},
		fail: (err) => {
    
    
			console.log("err: ------", err);
		}
	})
}
// 微信
async recursionCompressMP(urlList, callback) {
    
    
	let imgCompressList = []
	let imageSize = 0
	for (let itemUrl of urlList) {
    
    
		const result = await this.jumpImageCompress(itemUrl)
		if (result?.size < 150000) {
    
    
			this.tempImageList.push(itemUrl)
			continue
		}
		await this.getUserImageCompress(itemUrl, callback, result?.size)
	}
},


Compressed pictures mainly use the api 1 and uni.createCanvasContext provided by canvas to create a canvas drawing context.
2. CanvasContext.drawImage draws the image to the canvas.
3. CanvasContext.draw draws the previous description (path, deformation, style) in the drawing context to the canvas.
4. When the canvas is drawn, export the canvas as a picture, export the content of the specified area of ​​the current canvas to generate a picture of the specified size, and return the file path. uni.canvasToTempFilePath

//微信压缩图片
getUserImageCompress(itemUrl, callback, size){
    
    
	let that = this;
	return new Promise ((resolve, reject)=>{
    
    
		uni.getImageInfo({
    
    
			src: itemUrl,
			success: (res) => {
    
    
				//获取设备像素比,不获取最后图片展示有问题
				uni.getSystemInfo({
    
    
					success: function(info) {
    
    
						let ratio = 2;
						let canvasWidth = res.width //图片原始长宽
						let canvasHeight = res.height
						let compressWidth = res.width
						let quality = 0.1
						compressWidth = res.width - 120
						canvasHeight = res.height - 120
						while (canvasWidth > compressWidth || canvasHeight > canvasHeight) {
    
     // 保证宽高在400以内
							canvasWidth = Math.trunc(res.width / ratio)
							canvasHeight = Math.trunc(res.height / ratio)
							ratio++;
						}
						that.canvasWidth = canvasWidth
						that.canvasHeight = canvasHeight
						let ctx = uni.createCanvasContext('mycanvas')
						ctx.drawImage(res.path, 0, 0, canvasWidth, canvasHeight)
						ctx.draw(false, setTimeout(() => {
    
    
							uni.canvasToTempFilePath({
    
    
								canvasId: 'mycanvas',
								destWidth: canvasWidth,
								destHeight: canvasHeight,
								fileType: 'jpg',
								quality: quality,
								success: function(res1) {
    
    
									callback && callback(res1.tempFilePath) //拿到图片压缩后的临时路径
									uni.getFileInfo({
    
    
										filePath: res1.tempFilePath,
										success: (ress) => {
    
    
											console.log('压缩之后----',ress) //返回图片尺寸
											callback && callback(res1.tempFilePath)
											console.log('添加数据----', that.tempImageList)
											
											resolve(res1.tempFilePath)
											that.tempImageList.push(res1.tempFilePath)
										}
									})
								},
								fail: function(res) {
    
    
									console.log('canvas错误---',res.errMsg)
								}
							})
						}, 100)) //留一定的时间绘制canvas
					}
				})
			},
			fail: (e) => {
    
    
				console.log('错误----', e)
			}
		})
	})
},

Use the returned image size to control the compression ratio, and execute the compression function repeatedly.

//返回图片大小
jumpImageCompress (itemUrl) {
    
    	
	return new Promise((resolve, reject)=>{
    
    
		uni.getFileInfo({
    
    
			filePath: itemUrl,
			success: (res) => {
    
    
				console.log('压缩之前图片大小----',res) //返回图片尺寸
				resolve(res)
			},
			fail: (err) =>{
    
    
				reject(err)
			}
		})
	})
},
//h5
recursionCompressH5(url, callback) {
    
    
if (typeof url === 'string') {
    
    
		this.getUserImageCompressH5(url,callback)
	} else if (typeof url === 'object') {
    
    
		for (let itemImg of url) {
    
    
			this.getUserImageCompressH5(itemImg,callback)
		}
	}
},

Tips: Because the images drawn in the Canvas on the H5 side need to support cross-domain access to be successful. So uni.canvasToTempFilePath on the h5 end will return empty, so you need to use toBlob to convert it to a file, and then use createObjectURL to convert it to a url, so that you can get the image information. Controls the compression ratio.

// h5压缩图片
getUserImageCompressH5 (imgUrl,callback) {
    
    
	let that = this;
	return new Promise((resolve, reject)=>{
    
    
		uni.getImageInfo({
    
    
			src: imgUrl,
			success(res) {
    
    
				let canvasWidth = res.width; //图片原始长宽
				let canvasHeight = res.height;
				let img = new Image();
				img.src = res.path;
				console.log(5435435353)
				let canvas = document.createElement("canvas");
				let ctx = canvas.getContext("2d");
				canvas.width = canvasWidth / 2;
				canvas.height = canvasHeight / 2;
				ctx.drawImage(img, 0, 0, canvasWidth / 2, canvasHeight / 2);
				canvas.toBlob(function(fileSrc) {
    
    
					let imgSrc = window.URL.createObjectURL(fileSrc);
					uni.getFileInfo({
    
    
						filePath: imgSrc,
						success: (resFileInfo) => {
    
    
							if (resFileInfo.size > 150000) {
    
    
								//压缩后大于1M就继续压缩
								that.recursionCompressH5(imgSrc, callback);
								return;
							} else {
    
    
								callback && callback(imgSrc)
								resolve(imgSrc)
								that.tempImageList.push(imgSrc)
							}
						},
					});
				});
			}
		});
	})
},

2. Delete pictures

The delete function is very simple, just use the delete method of the array side directly splice.

deleteSelectImg(index) {
    
    
	this.tempImageList.splice(index, 1)
},

3. Rendering

As for the page ui structure, I won’t paste it here, and you can implement it according to your actual needs.
insert image description here


There is a problem

There are still some defects in controlling the compression ratio, and it does not perfectly solve the problem of compressing images of a specified size.
If you have any questions, please point out...

Guess you like

Origin blog.csdn.net/qq_43205326/article/details/130478034