uni-app开发微信小程序之H5压缩上传图片的问题怎么解决

这篇文章主要讲解了“uni-app开发微信小程序之H5压缩上传图片的问题怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“uni-app开发微信小程序之H5压缩上传图片的问题怎么解决”吧!

一、为什么要压缩图片

在使用uni-app开发小程序及H5的具体业务中,我们会遇到需要让用户上传本地图片的场景,随着现在的手机像素越来越高,图片的大小也越来越大,上传原图后一方面是难以上传成功,另一方面是上传成功后在列表中图片太大加载时间过长或者加载失败。若是直接提示用户 “无法上传xxM以上的图片” ,用户体验会不好,于是需要我们对用户上传的图片进行压缩。而不同平台之间压缩图片的方式并不完全兼容,需要提供不同的方法来实现。

二、图片压缩方式

uni-app官方提供了关于图片的一系列内置API

首先从选择图片开始

uni.chooseImage(OBJECT)      从本地相册选择图片或使用相机拍照。

// 该方法兼容小程序、H5
uni.chooseImage({
    count:1,
	sizeType: ['compressed'],
	success: res => { // success: 成功则返回图片的本地文件路径列表
	  let size = res.tempFiles[0].size // 选择第一张图片
	  console.log('图片大小', size, `${size/1000}KB`, `${size/1000/1000}MB`)
    }
})

图片选择完毕,下面就是不兼容的地方了 ⬇️

1. 微信小程序

小程序压缩图片的方式相对比较简单,不过有一定的局限性,仅对 jpg 格式有效。

uni.compressImage(OBJECT)     压缩图片接口,可选压缩质量。

uni-app开发微信小程序之H5压缩上传图片的问题怎么解决  uni-app 第1张

// 该方法兼容app和小程序,不兼容h6,且仅对jpg格式有效
uni.compressImage({
    src: src, // 图片路径
	quality: 10, // 图片压缩质量,0~100,默认80,仅对jpg有效
	success: res => {
	    console.log(res.tempFilePath,'压缩后的图片路径')
        // 接下来可以在这里处理图片上传
	}
})

实现图片上传

uni.getFileSystemManager()     获取全局唯一的文件管理器

readFile()     读取文件,可转换编码格式

// 该方法不兼容h6
uni.getFileSystemManager().readFile({
	filePath: path, // 要读取的文件路径
	encoding: 'base64', // 编码格式
	success: file => {
      wx_uploadImage({ // 调用接口实现上传图片,使用其他方式也可以
	    image: `data:image/png;base64,${file.data}`
	  }).then(res => {
	    console.log('上传图片成功', res)
	    this.image = res.storage_path // 赋值或者其他操作
	  })
	}
})

2. H5

H5需要使用另外的方式来压缩图片,这里用到了canvas。

- 分三步 -

1. 使用canvas限制图片大小(压缩图片),并转换为"blob路径";

uni.getImageInfo()     获取图片信息

uni.getImageInfo({
    src,
	success(res) {
	  console.log('压缩前', res);
	  let canvasWidth = res.width; // 图片原始宽度
	  let canvasHeight = res.height; // 图片原始高度
	  console.log('宽度-',canvasWidth,'高度-',canvasHeight);
	  let img = new Image();
	  img.src = res.path;
	  let canvas = document.createElement('canvas');
	  let ctx = canvas.getContext('2d');
	  // 这里根据要求限制图片宽高
	  if (canvasWidth >= 1000) {
	  	canvas.width = canvasWidth * .1;
	  } else {
	  	canvas.width = canvasWidth;
	  }
	  if (canvasHeight >= 1000) {
	  	canvas.height = canvasHeight * .1;
	  } else {
	  	canvas.height = canvasHeight;
	  }
	  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
	  //toBlob()方法创造Blob对象,用以展示canvas上的图片
	  canvas.toBlob(function(fileSrc) {
	  	let imgSrc = window.URL.createObjectURL(fileSrc);
	  	console.log('压缩后的blob路径', imgSrc);
	  });
    }
});

2. 将 "blob路径" 转换为 "blob文件"(待会转换base64格式图片需要用到 "blob文件" 的格式)

// 传入blob路径,.then()获取blob文件
httpRequest(src) {
    let that = this
	return new Promise((resolve, reject) => {
	  let xhr = new XMLHttpRequest()
	  xhr.open('GET', src, true)
	  xhr.responseType = 'blob'
	  xhr.onload = function (e) {
	      if (this.status == 200) {
	         let myBlob = this.response
	         let files = new window.File(
	            [myBlob],
	            myBlob.type,
	            { type: myBlob.type }
	         ) // myBlob.type 自定义文件名
	            resolve(files)
	         } else {
	            reject(false)
	         }
	      }
	  xhr.send()
    })
},

3. 将 "blob文件" 转换为 base64格式的图片,最后上传图片。

const fileReader = new FileReader()
fileReader.readAsDataURL(file) // 读取blob类型的图像文件(不是blob路径),读取成功触发onload方法,并得到result(base64格式的图片)
fileReader.onload = (event) => {
  console.log(fileReader.result,'fileReader.result - base64格式');
  if (fileReader.result) {
    // 调用wx_uploadImage接口,图片大小必须是1M以下,否则报错
    wx_uploadImage({
      image: fileReader.result
    }).then(res => {
      console.log('上传图片成功', res)
      this.image = res.storage_path
    })
  }
}

总结

总结一下以上逻辑经过封装后的完整代码:

// 使用条件编译区分微信小程序、H5的图片压缩上传方式
// 点击上传图片
chooseImage(){
  uni.chooseImage({
    count:1,
	sizeType: ['compressed'],
	success: res => {
	  let size = res.tempFiles[0].size
	  console.log('图片大小', size, `${size/1000}KB`, `${size/1000/1000}MB`)
	  			
	  let path = this.picture_show = res.tempFilePaths[0] //本地图片路径 - path
	  let file = res.tempFiles[0] //本地图片文件 - file
      let compressPath = ''
				
	  console.log(path,'路径');
	  console.log(file,'图片文件');
				
	  // 先压缩,再转换为base64图片,再上传
				
	  // #ifdef MP-WEIXIN
	  if (size > 1048576) {
		this.mp_compressImage(path)
	  } else {
		this.mp_filetobase64(path)
	  }
	  // #endif
				
	  // #ifdef H5
	  if (size > 1048576) {
	    this.h6_compressImage(path);
	  } else {
		this.h6_filetobase64(file)
	  }
	  // #endif
	}
  })
},
 
// 微信小程序 - 图片压缩方法
mp_compressImage(src) {
  let _this = this
  // 该方法兼容app和小程序,不兼容h6,且仅对jpg格式有效
  uni.compressImage({
    src: src, // 图片路径
	quality: 10, // 图片压缩质量,0~100,默认80,仅对jpg有效
	success: res => {
	  console.log(res.tempFilePath,'压缩后的图片路径')
      // 接下来可以在这里处理图片上传
      _this.mp_filetobase64(res.tempFilePath)
	}
  })
}
 
// 微信小程序 - 'blob路径'转base64图片的方法
mp_filetobase64(path) {
  // 该方法不兼容h6
  uni.getFileSystemManager().readFile({
	filePath: path, // 要读取的文件路径
	encoding: 'base64', // 编码格式
	success: file => {
      wx_uploadImage({ // 调用接口实现上传图片,使用其他方式也可以
	    image: `data:image/png;base64,${file.data}`
	  }).then(res => {
	    console.log('上传图片成功', res)
	    this.image = res.storage_path // 赋值或者其他操作
	  })
	}
  })
}
 
// h6 - 图片压缩方法
h6_compressImage(src) {
  let _this = this;
  uni.getImageInfo({
    src,
	success(res) {
	  console.log('压缩前', res);
	  let canvasWidth = res.width; // 图片原始宽度
	  let canvasHeight = res.height; // 图片原始高度
	  console.log('宽度-',canvasWidth,'高度-',canvasHeight);
	  let img = new Image();
	  img.src = res.path;
	  let canvas = document.createElement('canvas');
	  let ctx = canvas.getContext('2d');
	  // 这里根据要求限制图片宽高
	  if (canvasWidth >= 1000) {
	  	canvas.width = canvasWidth * .1;
	  } else {
	  	canvas.width = canvasWidth;
	  }
	  if (canvasHeight >= 1000) {
	  	canvas.height = canvasHeight * .1;
	  } else {
	  	canvas.height = canvasHeight;
	  }
	  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
	  //toBlob()方法创造Blob对象,用以展示canvas上的图片
	  canvas.toBlob(function(fileSrc) {
	  	let imgSrc = window.URL.createObjectURL(fileSrc);
	  	console.log('压缩后的blob路径', imgSrc);
        // 调用httpRequest方法,把bloburl转换成blob文件
		_this.httpRequest(imgSrc).then(res => {
		    console.log(res,'成功转换为blob文件');
		    _this.h6_filetobase64(res); // 调用方法,把blob文件转换成base64图片
		})
	  });
    }
  });
}
 
// 传入blob路径,.then()获取blob文件
httpRequest(src) {
    let that = this
	return new Promise((resolve, reject) => {
	  let xhr = new XMLHttpRequest()
	  xhr.open('GET', src, true)
	  xhr.responseType = 'blob'
	  xhr.onload = function (e) {
	      if (this.status == 200) {
	         let myBlob = this.response
	         let files = new window.File(
	            [myBlob],
	            myBlob.type,
	            { type: myBlob.type }
	         ) // myBlob.type 自定义文件名
	            resolve(files)
	         } else {
	            reject(false)
	         }
	      }
	  xhr.send()
    })
},
 
// h6 - 'blob文件'转base64图片的方法
h6_filetobase64(file) {
  const fileReader = new FileReader()
  fileReader.readAsDataURL(file) // 读取blob类型的图像文件(不是blob路径),读取成功触发onload方法,并得到result(base64格式的图片)
  fileReader.onload = (event) => {
    console.log(fileReader.result,'fileReader.result - base64格式');
    if (fileReader.result) {
      // 调用wx_uploadImage接口,图片大小必须是1M以下,否则报错
      wx_uploadImage({
        image: fileReader.result
      }).then(res => {
        console.log('上传图片成功', res)
        this.image = res.storage_path
      })
    }
  }
}

感谢各位的阅读,以上就是“uni-app开发微信小程序之H5压缩上传图片的问题怎么解决”的内容了,经过本文的学习后,相信大家对uni-app开发微信小程序之H5压缩上传图片的问题怎么解决这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是蜗牛博客,小编将为大家推送更多相关知识点的文章,欢迎关注!

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:niceseo99@gmail.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

评论

有免费节点资源,我们会通知你!加入纸飞机订阅群

×
天气预报查看日历分享网页手机扫码留言评论Telegram