前端借助Canvas实现压缩图片两种方法
一、具体代码
1、利用canvas压缩图片方法一
// 第一种压缩图片方法(图片base64,图片类型,压缩比例,回调函数)// 图片类型是指 image/png、image/jpeg、image/webp(仅Chrome支持)// 该方法对以上三种图片类型都适用 压缩结果的图片base64与原类型相同// 压缩结果存在误差 压缩比例只能作为范围参考function compressImg(base64, type, rate, callback) {// 声明一个Image对象var _img = new Image();// 将图片的地址赋予这个Image_img.src = base64;// 在图片加载完成后_img.onload = function () {// 创建canvas标签var _canvas = document.createElement("canvas");// 根据压缩比例设置canvas画布的宽高属性// this 指的是当前Image对象var w = this.width * rate;var h = this.height * rate;_canvas.setAttribute("width", w);_canvas.setAttribute("height", h);// 将图片渲染到canvas画布上 并设置渲染图片的宽高与画布的宽高一致_canvas.getContext("2d").drawImage(this, 0, 0, w, h);// 将canvas画布转换成对应类型的base64 var base64 = _canvas.toDataURL(type);// 将结果通过回调函数传递给方法的调用者callback(base64);};}
2、利用canvas压缩图片方法二
// 第二种压缩图片的方法(图片base64,图片类型,压缩比例,回调函数)// 该方法只能将图片压缩为为image/jpeg和image/webp两种类型的图片base64// 压缩结果存在一定误差 但比第一种方法更加准确function compressImg2(base64, rate, callback) {// 声明一个Image对象var _img = new Image();// 将图片的地址赋予这个Image_img.src = base64;// 在图片加载完成后_img.onload = function () {// 创建canvas标签var _canvas = document.createElement("canvas");// 设置canvas画布的宽高属性// this 指的是当前Image对象var w = this.width;var h = this.height;_canvas.setAttribute("width", w);_canvas.setAttribute("height", h);// 将图片渲染到canvas画布上 并设置渲染图片的宽高与画布的宽高一致_canvas.getContext("2d").drawImage(this, 0, 0, w, h);// 将canvas画布转换成base64 但第一个参数 转换后的图片类型只能为image/jpeg或image/webp// 根据压缩比例设置第二个参数图片质量(范围0-1)var base64 = _canvas.toDataURL('image/jpeg',rate);// 将结果通过回调函数传递给方法的调用者callback(base64);};}
3、调用压缩方法
// 图片base64
const base64 = 'data:image/****;base64,*****'
console.log('压缩前的图片---',base64);
// 获取图片的类型
const type =file.type// 调用压缩方法一
compressImg(res.data,type,0.6,(res2) => {console.log('这是第一种方法压缩0.6倍后的图片:---',res2)
})
// 调用压缩方法二
compressImg2(res.data,0.6,(res3) => {console.log('这是第二种方法压缩0.6倍后的图片:---',res3)
})
4、代码解析
这两种压缩图片的方法,是借助于Image和canvas实现的,整体区别不大,前半部分都是先将base64图片通过src渲染到一个Image中,当图片加载完成,触发onload事件后,创建一个canvas元素。区别主要是后半部分:
第一种方法是在创建canvas元素后,设置其宽高为图片原来宽高*压缩比例,然后将图片渲染到canvas元素上,同时设置渲染图片的宽高与canvas宽高一致,最后通过toDataURL(type)将canvas画布转成base64,参数type设置为原来的图片类型。其主要原理是通过压缩宽高来实现压缩图片的大小,但压缩结果误差较大。
第二种方法是在创建canvas元素后,设置其宽高与图片原本宽高一致,并将图片渲染到canvas元素上,同时设置渲染图片的宽高与canvas宽高一致,但是在通过toDataURL()将canvas画布转成base64时,第一个参数设置图片类型为:image/jpeg或image/webp,第二个参数设置图片的质量,范围是0-1。其主要原理是改变图片的质量来实现压缩图片的大小,压缩结果相对准确一些。
5、HTMLCanvasElement.toDataURL([type,encoderOptions])
该方法是canvas元素实例的一个方法,参数有两个,都是可选参数:type - 输出图片的类型,默认为image/png类型,常见的类型有:image/png、image/jpeg、image/webp(仅Chrome支持),图片的分辨率为 96dpi; encoderOptions - 当第一个参数指定图片类型为 image/jpeg 或 image/webp 的情况下,可以通过该参数设置输出图片的质量,取值区间是0-1,默认为0.92,当超出取值区间时,会使用默认值。
该方法的返回值是一个包含图片信息的Data URL,也可以看成图片的base64字符串。但如果调用该方法的canvas元素的宽或高为0,则返回值为字符串"data:,",、
浏览器兼容性:

6、相关文档:
前端FileReader对象实现图片file文件转base64
toDataURL
Data URL
相关文章:
前端借助Canvas实现压缩图片两种方法
一、具体代码 1、利用canvas压缩图片方法一 // 第一种压缩图片方法(图片base64,图片类型,压缩比例,回调函数)// 图片类型是指 image/png、image/jpeg、image/webp(仅Chrome支持)// 该方法对以上三种图片类型都适用 压缩结果的图片base64与原类型相同// …...
2023年美赛C题Wordle预测问题二建模及Python代码详细讲解
更新时间:2023-2-19 相关链接 (1)2023年美赛C题Wordle预测问题一建模及Python代码详细讲解 (2)2023年美赛C题Wordle预测问题二建模及Python代码详细讲解 (3)2023年美赛C题Wordle预测问题三、四…...
【算法】双指针
作者:指针不指南吗 专栏:算法篇 🐾或许会很慢,但是不可以停下来🐾 文章目录1.双指针分类2.双指针思想3.双指针应用1.双指针分类 常见问题分类 (1) 对于一个序列,用两个指针维护一段区间, 比如快速排序。 …...
Flutter-Widget-学习笔记
Widget 是整个视图描述的基础。 参考:https://docs.flutter.dev/resources/architectural-overview Widget 到底是什么呢? Widget 是 Flutter 功能的抽象描述,是视图的配置信息,同样也是数据的映射,是 Flutter 开发框…...
easyExcel 写复杂表头
写模板 模板图片: 实体类(这里没有用Data 是因为Lombok和easyExcal的版本冲突,在导入读取的时候获取不到值) package cn.iocoder.yudao.module.project.controller.admin.goods.vo;import com.alibaba.excel.annotation.ExcelI…...
关于线程池的执行流程和拒绝策略
使用线程池的好处为: 降低资源消耗:减少线程的创建和销毁带来的性能开销。 提高响应速度:当任务来时可以直接使用,不用等待线程创建 可管理性: 进行统一的分配,监控,避免大量的线程间因互相抢…...
【李忍考研传】二、约定
因为收学生证用了好些时间,李忍把学生证都交给班长后,就赶忙跑去食堂。远远地,他就看到那个瘦小的身影立在食堂正门前,那是他们约定每天午餐集合的地方。 “你咋这么慢啊……” “害!帮班长收东西耽误了点时间&#…...
2023-2-19 刷题情况
修改两个元素的最小分数 题目描述 给你一个下标从 0 开始的整数数组 nums 。 nums 的 最小 得分是满足 0 < i < j < nums.length 的 |nums[i] - nums[j]| 的最小值。nums的 最大 得分是满足 0 < i < j < nums.length 的 |nums[i] - nums[j]| 的最大值。nu…...
LeetCode笔记:Weekly Contest 333
LeetCode笔记:Weekly Contest 333 1. 题目一 1. 解题思路2. 代码实现 2. 题目二 1. 解题思路2. 代码实现 3. 题目三 1. 解题思路2. 代码实现 4. 题目四 比赛链接:https://leetcode.com/contest/weekly-contest-333 1. 题目一 给出题目一的试题链接如下…...
元数据管理 1
1、关于元数据管理原则说法正确的是 (知识点: 三月份模拟题)A.确保员工了解如何访问和使用元数据。B.制定、实施和审核元数据标准,以简化元数据的集成和使用。C.创建反馈机制,以便数据使用者可以将错误或过时的元数据反馈给元数据管理团队。D.以上都对正…...
统计二进制中比特1的个数
快速统计比特1的数量int CountBitOnes(int32_t n) {int result 0;for(;n;result) {n & n-1;}return result; }原理很简单,n-1会将n中最靠近结尾的1减一,这样n&n-1,n中最靠近结尾的1就变成了0;假设n 0b xxxxxxxx100n - 1…...
第三方实现跑马灯和手写实现跑马灯
目录第三方实现跑马灯手写实现跑马灯手写实现跑马灯【整体代码】自己细心研究一下上述代码第三方实现跑马灯 https://vue3-marquee.vercel.app/guide.html#changes-from-v2https://evodiaaut.github.io/vue-marquee-text-component/ 手写实现跑马灯 CSS部分 <style>.m…...
React Native Cannot run program “node“问题
概述 前几天mac重装系统了,用Android studio重新构建React native项目时,报Cannot run program "node"错误。 电脑系统为macOS 12.6.3 (Monterey),M1 Pro芯片。设备信息如下图所示: 完整错误信息如下图所示ÿ…...
python基于vue微信小程序 房屋租赁出租系统
目录 1 绪论 1 1.1课题背景 1 1.2课题研究现状 1 1.3初步设计方法与实施方案 2 1.4本文研究内容 2 2 系统开发环境 4 2.1 2.2MyEclipse环境配置 4 2.3 B/S结构简介 4 2.4MySQL数据库 5 2. 3 系统分析 6 3.1系统可行性分析 6 3.1.1经济可行性 6 3.1.2技术可行性 6 3.1.3运行可行…...
ThreadPoolExecutor管理异步线程笔记
为什么使用线程池? 线程的创建和销毁都需要不小的系统开销,不加以控制管理容易发生OOM错误。避免线程并发抢占系统资源导致系统阻塞。具备一定的线程管理能力(数量、存活时间,任务管理) new ThreadPoolExecutor(int …...
MotoSimEG-VRC教程:动态输送带创建以及示教编程与仿真运行
目录 任务描述 简易输送带外部设备创建 输送带模型添加与配置 工件安装到输送带 输送带输送工件程序编写与仿真运行 任务描述 在MotoSimEG-VRC中创建1条输送带,并且能够实现将工件从输送带起始点位置处输送到结束点位置处。 简易输送带外部设备创建 在MotoS…...
PyTorch 并行训练 DistributedDataParallel完整代码示例
使用大型数据集训练大型深度神经网络 (DNN) 的问题是深度学习领域的主要挑战。 随着 DNN 和数据集规模的增加,训练这些模型的计算和内存需求也会增加。 这使得在计算资源有限的单台机器上训练这些模型变得困难甚至不可能。 使用大型数据集训练大型 DNN 的一些主要挑…...
Golang实现ttl机制保存内存数据
ttl(time-to-live) 数据存活时间,我们这里指数据在内存中保存一段时间,超过期限则不能被读取到,与Redis的ttl机制类似。本文仅实现ttl部分,不考虑序列化和反序列化。 获取当前时间 涉及时间计算,这里首先介绍如何获取…...
js中数字运算结果与预期不一致的问题和解决方案
本文主要是和大家聊聊关于js中经常出现数字运算结果与预期结果不一致的问题,与及解决该问题的的方案。 一、问题现象 如:0.1 0.2的预期结果是0.3,但是在js中得到的计算结果却是0.30000000000000004,如下图所示 如:0…...
C++ Primer Plus 学习笔记(一)——基本类型
字节与字符 计算机内存的基本单位是位(bit),字节(byte)通常指的是8位的内存单元,从这个意义上来说,字节指的就是描述计算机内存量的度量单位。 C对字节的定义则有些不同,C字节由至…...
如何高效配置编程字体:Maple Mono的进阶优化方案
如何高效配置编程字体:Maple Mono的进阶优化方案 【免费下载链接】maple-font Maple Mono: Open source monospace font with round corner, ligatures and Nerd-Font icons for IDE and terminal, fine-grained customization options. 带连字和控制台图标的圆角等…...
百度网盘直链解析终极指南:5分钟告别限速下载的完整教程
百度网盘直链解析终极指南:5分钟告别限速下载的完整教程 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 还在为百度网盘那令人崩溃的下载速度而烦恼吗?…...
NoSleep:3种工作模式,解决Windows自动休眠的9大场景难题
NoSleep:3种工作模式,解决Windows自动休眠的9大场景难题 【免费下载链接】NoSleep Lightweight Windows utility to prevent screen locking 项目地址: https://gitcode.com/gh_mirrors/nos/NoSleep 你是否曾因Windows自动休眠而中断重要的远程演…...
Adafruit M4SK开发板外设接口实战:从I2C到PDM麦克风的嵌入式交互设计
1. 项目概述与核心价值如果你正在寻找一款既能玩转嵌入式图形界面,又能轻松连接各种传感器、执行器,并且自带丰富交互外设的开发板,Adafruit M4SK绝对是一个会让你眼前一亮的选项。它不像传统的单片机开发板那样“光秃秃”,而是将…...
别再只用AddModuleScore了!用irGSEA包一站式搞定单细胞基因集富集分析与8种可视化
单细胞基因集富集分析进阶指南:告别AddModuleScore,拥抱irGSEA的全能解决方案 在单细胞转录组数据分析中,基因集富集分析(Gene Set Enrichment Analysis, GSEA)是揭示细胞状态和功能特征的关键步骤。然而,许…...
EnigmaVB封包实战:如何为你的Qt小工具制作一个‘绿色单文件版’?
EnigmaVB封包实战:打造极致便携的Qt单文件应用 每次分享自己开发的Qt小工具时,你是否也厌倦了那些繁琐的依赖文件?想象一下,当你的同事或朋友收到一个双击即可运行的独立exe文件时,他们的表情会有多惊喜。这就是Enigma…...
uniApp H5项目从打包到上线:一站式解决跨域与Nginx部署
1. uniApp H5项目打包全流程解析 第一次用uniApp打包H5项目时,我对着空白页面和404错误整整折腾了两天。后来才发现,问题出在基础路径配置这个看似简单的环节上。uniApp打包H5和传统Vue项目有些不同,这里我把踩过的坑都总结成可复用的经验。 …...
Spec Kit性能优化:10个提升大规模项目规范处理效率的技巧
Spec Kit性能优化:10个提升大规模项目规范处理效率的技巧 【免费下载链接】spec-kit 💫 Toolkit to help you get started with Spec-Driven Development 项目地址: https://gitcode.com/GitHub_Trending/sp/spec-kit Spec Kit作为规范驱动开发&a…...
揭秘Clay印相底层渲染逻辑:为什么92%的用户调不出真实陶土肌理?
更多请点击: https://intelliparadigm.com 第一章:Clay印相的视觉本质与行业误读 Clay印相并非传统意义上的图像渲染技术,而是一种基于物理材质反射模型与神经感知先验耦合的视觉表征范式。其核心在于模拟黏土(Clay)在…...
Turbo模式突然失效?紧急修复指南:5分钟定位API网关超时、区域节点降级、token配额劫持三大隐性故障
更多请点击: https://intelliparadigm.com 第一章:Turbo模式突然失效?紧急修复指南:5分钟定位API网关超时、区域节点降级、token配额劫持三大隐性故障 Turbo模式并非原子性开关,其状态依赖于网关层、区域服务健康度与…...
