微信小程序图片压缩原来这么easy!

前言

在日常业务中我们可能会涉及到图片上传功能,现代影像设备大多数的照片都是几MB,甚至几十MB大小,大文件的上传会导致上传进度缓慢、占用云存储空间。所以,我们会根据需求来做图片压缩,将过大的图片文件压缩到指定大小内。

微信提供了一个图片压缩APIwx.compressImage(Object object)
APIIOS设备上仅支持压缩 JPG 格式图片,所以想要适配多机型、多格式的图片压缩,需要使用canvas标签,对图片进行重新绘制并导出。
canvas API 微信小程序更新过好多版,且很多API已经是停止维护状态。
在这里插入图片描述
自基础库2.9.0起,微信小程序提供 canvas 2d 接口(需指定 type 属性),同时支持同层渲染,原有接口不再维护。

接下来,我们对 Canvas 2D 图片压缩进行说明,同时 Canvas 2D 的部分内容会有提及。


开始

在开始之前,需要先了解这些知识:
使用 canvas 2d 时,我们需要在页面指定一个 canvas 标签

<view class="container">
  <canvas id="myCanvas" class="canvas-case" type="2d" style="border: 1px solid; width: 300px; height: 150px;" />
</view>

如果你仅仅只需要用到图片压缩功能,那么可以将 canvas 标签移到不可见的位置

.canvas-case{
  position: absolute;
  left: 0;
  top: 1000px;
}

我们通过获取元素节点的方式来获取 canvas 对象

const query = this.createSelectorQuery()
let dom = query.select('#myCanvas') // 获取 canvas 元素

在使用 canvas 前我们要先计算图片大小,计算公式如下:
计算图片当前大小和目标大小的比例:目标大小 / 图片当前大小
根据比例调整图片的尺寸:
新宽度 = 原始宽度 * √(目标大小 / 图片当前大小)
新高度 = 原始高度 * √(目标大小 / 图片当前大小)

// 宽度 > 最大限宽 -> 重置尺寸
if (width > config.maxWidth) {
    const ratio = config.maxWidth / width
    width = config.maxWidth
    height = height * ratio
}
// 高度 > 最大限高度 -> 重置尺寸
if (height > config.maxHeight) {
    const ratio = config.maxHeight / height
    width = width * ratio
    height = config.maxHeight
}

图片压缩

了解前面的知识后,我们开始通过 canvas 实现图片压缩

/**
  * 图片压缩
  * @param {object} file 图片信息:width、height、type、path 
  * @param {string} canvasId canvas的id名 
  * @param {object} config 限制最大宽高
  * @returns 压缩完成后的图片path 
*/
async contraction(file, canvasId, config = { maxWidth: 1024, maxHeight: 768 }) {
  try {
        let ctxInfo = await new Promise((resolve, reject) => {
        // 获取图片原始宽高
        let width = file.width
        let height = file.height

        // 计算图片当前大小和目标大小的比例:目标大小 / 图片当前大小
        // 根据比例调整图片的尺寸:
        // 新宽度 = 原始宽度 * √(目标大小 / 图片当前大小) 
        // 新高度 = 原始高度 * √(目标大小 / 图片当前大小)
        // 宽高同比例调整
        // 宽度 > 最大限宽 -> 重置尺寸
        if (width > config.maxWidth) {
            const ratio = config.maxWidth / width
            width = config.maxWidth
            height = height * ratio
        }
        // 高度 > 最大限高度 -> 重置尺寸
        if (height > config.maxHeight) {
            const ratio = config.maxHeight / height
            width = width * ratio
            height = config.maxHeight
        }

        // 获取canvas元素
        const query = this.createSelectorQuery()
        let dom = query.select(`#${canvasId}`)
        dom.fields({ node: true, size: true })
        .exec((res) => {
            // Canvas 对象
            const canvas = res[0].node
            // 渲染上下文
            const ctx = canvas.getContext('2d')

            // 根据设备像素比处理尺寸 = 大小 * 设备像素
            const dpr = wx.getSystemInfoSync().pixelRatio
            canvas.width = width * dpr
            canvas.height = height * dpr
            ctx.scale(dpr, dpr)

            //创建img对象
            let img = canvas.createImage();
            img.src = file.path; // 给图片添加路径
            //图片加载完毕
            img.onload = function () {
            // 将图片绘制到 canvas
            ctx.drawImage(img, 0, 0, width, height)
            // 生成图片
            wx.canvasToTempFilePath({
                   canvas,
                   x: 0,
                   y: 0,
                   destWidth: width,
                   destHeight: height,
                   success(res) {
                           resolve(res); // 生成临时文件路径
                    }
                 })
                }
              })
            })
       return ctxInfo
  } catch (err) { console.log(err); }
},

拆解上面的代码:
1、压缩图片大小,重置宽高
2、通过const canvas = res[0].node 创建 canvas 对象
3、通过 const ctx = canvas.getContext('2d') 渲染上下文
4、然后获取当前设备信息,给canvas设置尺寸大小,公式为:(宽&高) * 设备像素比, 防止图像失真
5、创建img对象,给img对象添加图片路径
6、图片加载完毕后,将图片绘制到canvas
7、生成图片

你可能会需要获取图片尺寸信息,例如:宽、高、图片类型、图片地址等,这里我封装了一个获取图片信息的函数,你只需要传入图片地址就可以获得图片信息。

/* 获取图片信息
 * @param {string} tempFilePath 图片路径
 * @returns 图片信息
 */
async getImgInfo(tempFilePath) {
	try {
		let image = await new Promise((resolve, reject) => {
			wx.getImageInfo({
				src: tempFilePath,
				success(res) {
					let imgInfo = {
						type: res.type,
						height: res.height,
						width: res.width,
						path: res.path
					}
					resolve(imgInfo)
				},
				fail(err) {
					reject(err)
				}
			})
		})
		return image
	} catch (err) { console.log(err); }
},

实际调用:

async afterRead(file) {
	let imgInfo = await this.getImgInfo(file.tempFilePath);  // 获取图片信息
  let ctxInfo = await this.contraction(imgInfo, 'myCanvas');  // 图片压缩
  // 后续保存操作.....
}

压缩前:
在这里插入图片描述
压缩后:
在这里插入图片描述


如果你觉得本文章不错,欢迎点赞👍、收藏💖、转发✨哦~
阅读其它:
css绘制一个Pinia小菠萝
Module理解及使用
深入理解Promise
运算符:指数-链判断-Null判断-逻辑赋值
微信小程序动态生成表单来啦!你再也不需要手写表单了!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

线性回归简介

线性回归简介 1、情景描述2、线性回归 1、情景描述 假设&#xff0c;我们现在有这么一张图&#xff1a; 其中&#xff0c;横坐标x表示房子的面积&#xff0c;纵坐标y表示房价。我们猜想x与y之间存在线性关系&#xff1a; y k x b ykxb ykxb 现在&#xff0c;思考一个问题&…

期末加油站-图像处理期末知识点汇总

第三章&#xff1a;图像增强 一、概念 1.图像增强是通过某种技术有选择地突出对某一具体应用有用的信息&#xff0c;削弱或抑制一些无用的信息。 2. 图像增强处理不是无损处理&#xff0c;不能增加原图像的信息。 3. 图像增强按所处理的对象不同可分为&#xff1a; 灰度图像增…

腾讯面试:SaaS多租户,如何设计?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业网易、美团、字节、如阿里、滴滴、极兔、有赞、希音、百度、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; 多租户设计&#xff0c;如何 技术选型&#xff…

Vue+ElementUI+nodejs学生宿舍报修管理系统68ozj

本站是一个B/S模式系统&#xff0c;采用vue框架&#xff0c;MYSQL数据库设计开发&#xff0c;充分保证系统的稳定性。系统具有界面清晰、操作简单&#xff0c;功能齐全的特点&#xff0c;使得学生宿舍信息管理系统管理工作系统化、规范化。本系统的使用使管理人员从繁重的工作中…

爬虫字典生成工具,CeWL使用教程

爬虫字典生成工具,CeWL使用教程 1.工具概述2.参数解析3.使用实例1.工具概述 CeWL 是一个 ruby 应用程序,它将给定的 URL 爬到指定的深度,可以选择跟随外部链接,并返回一个单词列表,然后可用于密码破解者 Cewl 是黑客武器库中的强大工具,因为它允许创建有针对性的单词列…

Python学习路线 - Python语言基础入门 - Python基础综合案例 - 数据可视化 - 地图可视化

Python学习路线 - Python语言基础入门 - Python基础综合案例 - 数据可视化 - 地图可视化 基础地图使用基础地图演示基础地图演示 - 视觉映射器 疫情地图-国内疫情地图案例效果数据整理 疫情地图-省级疫情地图省疫情地图 基础地图使用 基础地图演示 代码示例&#xff1a; &quo…

智能优化算法应用:基于蛇优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于蛇优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于蛇优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.蛇优化算法4.实验参数设定5.算法结果6.参考文…

实习课知识整理4:点击某个商品如何跳转到并展示出商品详情页

项目情景&#xff1a;当我们点击某个商品时&#xff0c;我们需要查看商品的具体的信息并进行购买的操作 简单理解以下就是&#xff0c;当我们点击一个url链接时&#xff0c;该链接需要携带一个参数到后端&#xff0c;一般设为商品的Id&#xff0c;然后后端通过Id从数据库中查找…

idea structure视图介绍

作用 idea的Structure视图可以辅助查看代码结构 如何呼出Structure视图&#xff1f; Alt 7 Ctrl F12 侧边栏点Structure 我的常用配置 1、选Show Toolbar&#xff0c;便于使用功能按钮 2、使用Float视图&#xff0c;悬浮于窗口表面&#xff0c;可以使用 ShiftEsc来退出…

工业互联网:数字化制造的未来

引言 在当今的数字化时代&#xff0c;制造业正经历着革命性的变革。工业互联网&#xff08;Industrial Internet of Things"&#xff0c;简称 IIoT&#xff09;作为这一变革的核心引擎&#xff0c;正在重新定义现代工业和制造。本文将探讨工业互联网的基础、关键技术、应…

【SpringCloud笔记】(8)服务网关之GateWay

GateWay 概述简介 官网地址&#xff1a; 上一代网关Zuul 1.x&#xff1a;https://github.com/Netflix/zuul/wiki&#xff08;有兴趣可以了解一下&#xff09; gateway&#xff1a;https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/…

【开放集检测】OpenGAN: Open-Set Recognition via Open Data Generation 论文阅读

文章目录 英语积累为什么使用GAN系列网络进行开放集检测摘要1. 前言2. 相关工作开集检测基于GAN网络的开集检测基于暴露异常数据的开集检测 3. OpenGAN3.1 公式建模3.1.1 二分类方法存在问题如何解决 3.1.2 使用合成数据存在问题如何解决 3.1.3 OpenGAN3.1.4 模型验证 3.2 先前…

机器视觉工程师,面对难以实现的需求时,应该如何应对?

作为一名机器视觉工程师&#xff0c;在工作中难免会遇到一些难以实现&#xff0c;奇形怪状的需求&#xff0c;各种五花八门&#xff0c;奇葩需求&#xff0c;顿时头疼不已。同时销售要接订单&#xff0c;机器视觉工程师也要做项目提升自我&#xff0c;销售与技术矛盾本身是存在…

vivado 输出延迟

输出延迟 set_output_delay命令指定输出端口相对于设计接口处的时钟边缘。 当考虑应用板时&#xff0c;此延迟表示以下各项之间的相位差&#xff1a; 1.数据从FPGA的输出封装引脚通过板传播到另一个设备&#xff0c;以及 2.相对基准板时钟。 输出延迟值可以是正的&#xf…

基于javaSpringbootmysql的小型超市商品展销系统01635-计算机毕业设计项目选题推荐(免费领源码)

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作…

AndroidStudio无法新建aidl文件解决办法

我用的 AS 版本是 Android Studio Giraffe | 2022.3.1 Build #AI-223.8836.35.2231.10406996, built on June 29, 2023 右键新建 aidl 文件&#xff0c; 提示 (AIDL File)Requires setting the buildFeatures.aidl to true in the build file 解决办法 修改 app 的 build.…

第26关 K8s日志收集揭秘:利用Log-pilot收集POD内业务日志文件

------> 课程视频同步分享在今日头条和B站 大家好&#xff0c;我是博哥爱运维。 OK&#xff0c;到目前为止&#xff0c;我们的服务顺利容器化并上了K8s&#xff0c;同时也能通过外部网络进行请求访问&#xff0c;相关的服务数据也能进行持久化存储了&#xff0c;那么接下来…

C语言进阶---------作业复习

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

MySQL升级版本(Linux环境)

摘要 由于我们在做部署的时候会部署MySQL&#xff0c;但是版本可能各种各样&#xff0c;而且我们服务器会定期的进行漏洞扫描&#xff0c;因此我们在遇到MySQL的相关漏洞时&#xff0c;一般漏洞报告中会提示出解决方案&#xff0c;一般来时就是升级软件的版本&#xff0c;因此…

虚拟机安装

带你解密Linux的【Vm】-CSDN博客https://blog.csdn.net/lz17267861157/article/details/134031133