uni-app开发微信小程序,H5 关于压缩上传图片的问题

news2025/2/24 8:42:50

文章目录

前言

一、为什么要压缩图片

二、图片压缩方式

1. 微信小程序​​​​​​​

2. 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
      })
    }
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/405813.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入了解-微信开发者工具

主要介绍微信开发者工具如何编译小程序代码,如何实现小程序模拟器以及如何调试小程序。 1 简介 虽然在开发语言层面小程序与传统的网页差别不大:是使用JavaScript 脚本语言编写逻辑代码、使用类似于HTML的WXML来描述页面的结构、使用类似于CSS的WXSS来…

B/S架构

目录 一、什么是B/S架构 二、三层架构 三、Active技术 四、网络节点 五、分布式网络计算 六、JavaScript 一、什么是B/S架构 1.B/S架构是软件系统体系结构,是指浏览器-Web服务器(Broswer-Server),采用三层架构,即表现层、业务逻辑层、数据访问…

十分钟带你入门Chrome插件开发

一、简述 我们所说的chrome插件一般都是指chrome扩展程序(Chrome Extension)。chrome插件是一个用Web技术开发、用来增强浏览器功能的软件,它其实就是一个由HTML、CSS、JS、图片等资源组成的一个.crx后缀的文件。chrome插件除了Chrome浏览器…

【TFS-CLUB社区 第4期赠书活动】〖Flask Web全栈开发实战〗等你来拿,参与评论,即可有机获得

文章目录❤️‍🔥 赠书活动 - 《Flask Web全栈开发实战》❤️‍🔥 编辑推荐❤️‍🔥 内容提要❤️‍🔥 赠书活动 → 获奖名单❤️‍🔥 赠书活动 - 《Flask Web全栈开发实战》 内容简介: 《Flask Web全栈开发…

flex布局 多种方法让两个盒子分布在左右两边

方法一&#xff1a; 一个父盒子里面包含了两个子盒子的&#xff0c;可以用justify-content:space-between属性 <div classparent> <div class"left"></div> <div class"right"></div> </div> .parent { disp…

FreeRTOS(教程非常详细)

概述&#xff1a; 之前写了关于FreeRTOS的部分内容&#xff0c;为了方便阅读&#xff0c;现在给汇总到一起了。全部学习完后&#xff0c;恭喜你对FreeRTOS有了更深的认知。 第一章 FreeRTOS移植到STM32 第二章 FreeRTOS创建任务 第三章 FreeRTOS任务管理 第四章 FreeRTOS消…

【springcloud 微服务】Spring Cloud Ribbon 负载均衡使用策略详解

目录 一、前言 二、什么是Ribbon 2.1 ribbon简介 2.1.1 ribbon在负载均衡中的角色 2.2 客户端负载均衡 2.3 服务端负载均衡 2.4 常用负载均衡算法 2.4.1 随机算法 2.4.2 轮询算法 2.4.3 加权轮询算法 2.4.4 IP地址hash 2.4.5 最小链接数 三、Ribbon中负载均衡策略…

Unity 实现A* 寻路算法

前言 A* 寻路算法是什么 游戏开发中往往有这样的需求&#xff0c;让玩家控制的角色自动寻路到目标地点&#xff0c;或是让 AI 角色移动到目标位置&#xff0c;实际的情况可能很复杂&#xff0c;比如地图上有无法通过的障碍或者需要付出代价&#xff08;时间或其他资源&#x…

XShell免费版的安装配置教程以及使用教程(超级详细、保姆级)

目录 一、 XShell的作用 二、 下载免费版XShell 三、 安装XShell 四、使用XShell连接Linux服务器 一、 XShell的作用 XShell 是一种流行且简单的网络程序&#xff0c;旨在模拟虚拟终端。XShell可以在Windows界面下来访问远端不同系统下的服务器&#xff0c;从而比较好的达到…

11.落地:微服务架构灰度发布方案

前置知识 1.nacos 服务注册与发现 2.本地负载均衡器算法 3.gateway 网关 4.ThreadLocal 1.什么是灰度发布&#xff1f; 2.什么是灰度策略? 3.灰度发布落地方案有哪些 4.灰度发布架构设计原理 nginxlua&#xff1f; 5.如何基于GateWayNacos构建灰度环境 6.GateWay负载均衡…

【云原生 • Kubernetes】认识 k8s、k8s 架构、核心概念点介绍

目录 一、Kubernetes 简介 二、Kubernetes 架构 三、Kunbernetes 有哪些核心概念&#xff1f; 1. 集群 Cluster 2. 容器 Container 3. POD 4. 副本集 ReplicaSet 5. 服务 service 6. 发布 Deployment 7. ConfigMap/Secret 8. DaemonSet 9. 核心概念总结 一、Kubern…

java程序员转正述职报告PPT

新公司转正述职报告&#xff0c;花了些时间准备了ppt和讲稿&#xff0c;这里分享一下 述职报告 时间过得很快&#xff0c;转眼就已经三个月了&#xff0c;三个月时间不长&#xff0c;完成的工作也有限&#xff0c;但是在这些工作中&#xff0c;我也学到了很多&#xff0c;现在…

Linux命令大全:2W多字,一次实现Linux自由

前言 大家好&#xff0c;我是40岁老架构师尼恩&#xff0c;Linux 的学习对于一个程序员的重要性是不言而喻的。 学好它却是程序员必备修养之一。 同时&#xff0c;也是很多公司的面试题。 比如说&#xff0c;曾有一个网易的面试题是&#xff1a; 聊聊&#xff1a;你常用的几…

docker入门,这一篇就够了。

Docker入门&#xff0c;这一篇就够了。 Docker容器虚拟化平台。 前言 接触docker很长时间了&#xff0c;但是工作中也没有用到&#xff0c;所以总是学了忘&#xff0c;忘了学。不过这次&#xff0c;我打算跟大家分享一下我的学习历程&#xff0c;也算是我的独特的复习笔记&…

双目三维重建系统(双目标定+立体校正+双目测距+点云显示)Python

双目三维重建系统(双目标定立体校正双目测距点云显示)Python 目录 双目三维重建系统(双目标定立体校正双目测距点云显示)Python 1.项目结构 2. Environment 3.双目相机标定和校准 (0) 双目摄像头 (1) 采集标定板的左右视图 (2) 单目相机标定和校准 (3) 双目相机标定和…

毕业论文案例-LDA主题模型实现文本聚类

本文结构框架引言LDA主题模型的预备知识&#xff08;1&#xff09;多项式分布 Multinomial Distribution&#xff08;2&#xff09;狄利克雷分布 Dirichlet Distribution&#xff08;3&#xff09;共轭分布 Conjugate Distribution&#xff08;4&#xff09;吉普斯采样 Gibbs S…

springboot整合webSocket(看完即入门)

webSocket1、什么是webSocket&#xff1f;2、webSocket可以用来做什么?3、webSocket协议4、服务端WebSocket操作类5、客户端1、什么是webSocket&#xff1f; WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单&am…

100天精通Python(可视化篇)——第77天:数据可视化入门基础大全(万字总结+含常用图表动图展示)

文章目录1. 什么是数据可视化&#xff1f;2. 为什么会用数据可视化&#xff1f;3. 数据可视化的好处&#xff1f;4. 如何使用数据可视化&#xff1f;5. Python数据可视化常用工具1&#xff09;Matplotlib绘图2&#xff09;Seaborn绘图3&#xff09;Bokeh绘图6. 常用图表介绍及其…

【Windows】六种正确清理C盘的方法,解决你的红色烦恼

如何正确的清理C盘前言清理方法1. 利用Windows自己附带的磁盘清理工具2. 开启自动清理3. 通过“配置存储感知或立即运行”来清理4. 管理C盘中的程序5. 系统文件夹转移6. 将C盘现有内容转移到别的盘参考链接前言 Windows操作系统一般是安装在磁盘驱动器的C盘中&#xff0c;运行…

D435i相机的标定及VINS-Fusion config文件修改

引言 当我们想使用D435i相机去跑VINS-Fusion时&#xff0c;如果不把标定过的相机信息写入config文件中就运行&#xff0c;这样运动轨迹会抖动十分严重&#xff0c;里程计很容易漂。接下来将介绍如何标定D435i相机&#xff0c;并设置VINS-Fusion的config文件。 一 标定前的准备…