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

 更新时间:2023年03月02日 10:15:10   作者:举个李子ⁱ  
这次项目中做了一个图片上传,要求是大于2MB的就压缩成2MB一下的再上传,下面这篇文章主要给大家介绍了关于uni-app开发微信小程序之H5压缩上传图片的问题,需要的朋友可以参考下

前言

关于微信小程序、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)     压缩图片接口,可选压缩质量。

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

实现图片上传

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

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

// 该方法不兼容h5
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.h5_compressImage(path);
	  } else {
		this.h5_filetobase64(file)
	  }
	  // #endif
	}
  })
},
 
// 微信小程序 - 图片压缩方法
mp_compressImage(src) {
  let _this = this
  // 该方法兼容app和小程序,不兼容h5,且仅对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) {
  // 该方法不兼容h5
  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 // 赋值或者其他操作
	  })
	}
  })
}
 
// h5 - 图片压缩方法
h5_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.h5_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()
    })
},
 
// h5 - 'blob文件'转base64图片的方法
h5_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压缩上传图片内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JS简单获得节点元素的方法示例

    JS简单获得节点元素的方法示例

    这篇文章主要介绍了JS简单获得节点元素的方法,结合实例形式分析了javascript获取页面节点元素及修改元素属性相关操作技巧,需要的朋友可以参考下
    2018-02-02
  • JavaScript截断字符串的方法

    JavaScript截断字符串的方法

    这篇文章主要介绍了JavaScript截断字符串的方法,涉及javascript字符串截取的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • 详解JavaScript如何生成临时链接

    详解JavaScript如何生成临时链接

    这篇文章主要为大家详细介绍了JavaScript如何生成临时链接的相关知识,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考下
    2024-02-02
  • JavaScript动画原理之如何使用js进行动画效果的实现

    JavaScript动画原理之如何使用js进行动画效果的实现

    在现在做页面很多时候都会用上动画效果,比如下拉菜单,侧边搜索栏,层的弹出与关闭等等,下面这篇文章主要给大家介绍了关于JavaScript动画原理之如何使用js进行动画效果实现的相关资料,需要的朋友可以参考下
    2023-04-04
  • JavaScript实现动画打开半透明提示层的方法

    JavaScript实现动画打开半透明提示层的方法

    这篇文章主要介绍了JavaScript实现动画打开半透明提示层的方法,涉及javascript操作DOM的相关技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • JavaScript实现时钟滴答声效果

    JavaScript实现时钟滴答声效果

    本文给大家分享一段js实例代码实现时钟滴答声效果,效果逼真,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-01-01
  • 一文详解如何在uniapp中设置隐私政策弹窗

    一文详解如何在uniapp中设置隐私政策弹窗

    在将uniapp打包成APP端时,上架到应用市场的时候需要配置隐私弹窗,下面这篇文章主要给大家介绍了关于如何在uniapp中设置隐私政策弹窗的相关资料,需要的朋友可以参考下
    2023-01-01
  • 10个功能强大的JavaScript动画库分享

    10个功能强大的JavaScript动画库分享

    动画,从人群中脱颖而出、吸引访客注意力的绝佳方式,本文将给大家分享10 个功能强大的 JavaScript 动画库,有了这 10 个功能强大的 JavaScript 库,创建动画再简单不过了,感兴趣的同学可以参考阅读
    2023-09-09
  • JavaScript类的继承多种实现方法

    JavaScript类的继承多种实现方法

    这篇文章主要介绍了JavaScript类的继承多种实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • 微信小程序中使用wxss加载图片并实现动画效果

    微信小程序中使用wxss加载图片并实现动画效果

    记录微信小程序中使用wxss加载图片并实现动画的方式,最终实现loading效果。本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友参考下吧
    2018-08-08

最新评论