UniApp实现图片处理与图片上传的设计与开发实践

一、UniApp简介

UniApp是一款基于Vue.js框架的跨平台开发工具,使用UniApp可以快速开发出同时适配多个平台的应用。UniApp可以将同一套代码快速打包为微信小程序、支付宝小程序、H5、App等多个平台的应用。此外,UniApp还提供了一些开箱即用的组件和插件,开发者可以快速构建出美观且功能丰富的应用。

二、图片处理与图片上传的设计

1. 图片处理的需求

在应用中,用户经常需要上传图片,但是上传的图片往往需要进行一些处理,例如压缩、裁剪、旋转等操作。因此,我们需要在应用中提供这些图片处理的功能。

一些关键点:

使用canvas对图片进行处理

通过设定画布的宽高,将图片进行裁剪、缩放等操作

使用drawImage()方法,将图片绘制在画布上

使用canvas.toDataURL()方法将绘制后的画布转换为base64格式的图片

2. 图片上传的需求

在应用中,用户上传的图片需要存放在服务器上,因此我们需要提供一个图片上传的功能。上传的图片需要满足一下要求:

支持上传多张图片

上传的图片需要进行压缩处理

上传的图片需要进行文件格式的验证

上传的图片需要支持断点续传

一些关键点:

使用uni.uploadFile()方法上传图片

使用Promise.all()方法,实现多张图片的上传

使用canvas.toBlob()方法,将处理后的图片转换成blob格式的文件

使用File对象,对文件的格式、大小进行验证

使用阿里云OSS对象存储实现文件上传

设置分片上传,实现断点续传

三、图片处理与图片上传的开发实践

1. 图片处理的开发

图片处理的开发比较简单,主要是通过canvas对图片进行处理。

// 获取图片画布和画布上下文

const canvas = uni.createCanvasContext('photo-canvas', this);

// 加载图片

canvas.drawImage(imgPath, 0, 0, imgWidth, imgHeight);

// 将画布转换为base64格式图片

canvas.toDataURL('png', 0.7, (res) => {

const base64Img = res.replace(/data:image\/(jpeg|png);base64,/, '');

// 将base64格式转为blob格式文件

this.compressImage(base64Img).then((file) => {

// 对文件进行上传

this.uploadFile(file);

})

});

2. 图片上传的开发

图片上传的开发相对较为复杂,需要考虑多个方面的问题。

首先,在上传图片前,需要对图片进行压缩处理,然后再进行上传。这里的压缩处理需要考虑到多个方面的问题,例如图片大小、图片质量、图片格式等。

// 压缩图片

compressImage(base64Img) {

const imgSize = base64Img.length / 1024 / 1024;

let maxSize = 1;

let maxQuality = 0.8;

let fileType = 'jpeg';

if (imgSize > 10) {

maxSize = 2;

} else if (imgSize <= 0.7) {

maxSize = 1;

} else {

maxSize = (imgSize / 3).toFixed(0);

maxSize = maxSize <= 1 ? 1 : maxSize;

}

const canvas = document.createElement('canvas');

const img = new Image();

return new Promise((resolve, reject) => {

img.src = base64Img;

img.onload = () => {

const imgWidth = img.width;

const imgHeight = img.height;

let cvsWidth, cvsHeight;

if (imgWidth > imgHeight) {

cvsWidth = maxSize * 1024;

cvsHeight = (imgHeight / imgWidth * maxSize * 1024).toFixed(0);

} else {

cvsHeight = maxSize * 1024;

cvsWidth = (imgWidth / imgHeight * maxSize * 1024).toFixed(0);

}

canvas.width = cvsWidth;

canvas.height = cvsHeight;

const ctx = canvas.getContext('2d');

ctx.drawImage(img, 0, 0, imgWidth, imgHeight, 0, 0, cvsWidth, cvsHeight);

canvas.toBlob((blob) => {

const compressFile = new File([blob], `test.${fileType}`, { type: `image/${fileType}` });

resolve(compressFile);

}, `image/${fileType}`, maxQuality);

}

})

}

其次,在图片上传时,需要考虑到图片上传的文件格式、文件大小的验证。这里我们可以通过File对象的一些方法,对文件进行验证。

// 验证文件大小是否合法

isValidFileSize(file) {

const fileSize = file.size / 1024 / 1024;

return fileSize <= this.fileMaxSize;

},

// 验证文件格式是否合法

isValidFileType(file) {

const fileType = file.type.split('/')[1];

return this.fileTypes.includes(fileType);

},

// 判断文件是否有效

isValidFile(file) {

return this.isValidFileSize(file) && this.isValidFileType(file);

}

最后,在文件上传时,我们可以利用阿里云OSS对象存储的SDK,实现文件的断点续传。

// 初始化OSS实例

initOSSClient() {

// ...

const config = {

aliyunUrl: process.env.UNI_ENV.aliyunUrl,

region: process.env.UNI_ENV.aliyun_os_region,

accessKeyId: process.env.UNI_ENV.aliyun_os_access_key_id,

accessKeySecret: process.env.UNI_ENV.aliyun_os_access_key_secret,

bucket: process.env.UNI_ENV.aliyun_os_bucket

};

return new OSS(config);

},

// 上传文件

uploadFile(file) {

if (this.isValidFile(file)) {

const client = this.initOSSClient();

const expire = new Date().getTime() + (this.expireMinute * 60 * 1000);

const options = {

progress: (percentage) => { // 上传进度

this.uploadProgress = (percentage * 100).toFixed(0);

},

meta: { // 自定义元数据

fileType: file.type,

fileName: file.name,

fileTimeStamp: new Date().getTime(),

expire: expire,

from: this.from

}

};

client.multipartUpload(this.genUploadFileName(), file, options).then((data) => {

// 上传成功

}).catch((err) => {

// 上传失败

});

}

}

四、总结

图片处理与图片上传是一个常见的开发需求,在UniApp中的实现主要是利用canvas进行图片处理,在使用uni.uploadFile()方法上传图片时,通过Promise.all()方法实现多张图片的上传,使用阿里云OSS对象存储实现文件上传。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。