赞
踩
小程序上传图片,或者拍照上传图片,并附带兼容H5上传图片方法,压缩图片。
支持选择相册和拍照,可以使用uniapp提供的api,当然也可以自己去封装自己想要的样式,我这里直接是使用了uni的方法。uni.chooseImage
配置sourceType: ['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)
}
},
压缩图片主要用canvas提供的api
1、uni.createCanvasContext 创建 canvas 绘图上下文。
2、CanvasContext.drawImage 绘制图像到画布。
3、CanvasContext.draw将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中。
4、当canvas绘制完成后,将canvas导出成为图片,把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径。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) } }) }) },
利用返回的图片大小去控制压缩的比例,重复执行压缩函数。
//返回图片大小
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:因为H5端 Canvas 内绘制的图像需要支持跨域访问才能成功。所以h5端uni.canvasToTempFilePath会返回为空,所以需要使用toBlob转为文件,再利用createObjectURL转为url,这样就可以获取到图片信息。控制压缩比例。
// 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) } }, }); }); } }); }) },
删除功能很简单,直接使用数组方的删除方法splice
就可以了。
deleteSelectImg(index) {
this.tempImageList.splice(index, 1)
},
至于页面ui结构,这里就不粘贴了,可以根据自己实际需求去实现。
在控制压缩比例的地方,还有一些缺陷,并没有很完美的解决压缩指定大小图片问题。
如有问题欢迎指出…
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。