使用canvas进行图片压缩(前端图片压缩核心处理)

2023-10-30

一、原理:实际上就是利用canvas进行重新绘制

1、先将图片的file文件转成baseURL
2、创建一个image标签去接收文件获取图片的宽高和比例。
3、创建canvas画布设置画布的大小。
4、将图片绘制到canvas上面。
5、对canvas进行压缩处理,获得新的baseURL
6、将baseURL转化回文件。

二、核心代码

/**
 * 压缩图片
 * @param file 压缩文件
 * @param compressThreshold 开启压缩的阈值,默认 5M
 * @param openCompress 是否开启压缩,默认 true
 * @param pictureQuality 压缩比,默认 0.92
 * @returns
 */
export const compressFile = (
  file: File,
  compressThreshold = 5,
  openCompress = true,
  pictureQuality = 0.92
) => {
  console.log('========== Entry Compress File Function ==========');
  console.log('before compress file: ', file);
  //判断是否是图片类型
  const isAccept = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif'].includes(file.type);
  if (isAccept) {
    const fileSize = file.size / 1024 / 1024;
    console.log('before compress, the file size is : ', fileSize.toFixed(2) + ' M');
    //当开启图片压缩且图片大小大于等于压缩阈值,进行压缩
    if (fileSize >= compressThreshold && openCompress) {
      //判断浏览器内核是否支持base64图片压缩
      if (typeof FileReader === 'undefined') {
        return file;
      } else {
        try {
          return new Promise(resolve => {
            //声明FileReader文件读取对象
            const reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = () => {
              // 生成canvas画布
              const canvas = document.createElement('canvas');
              // 生成img
              // const img = document.createElement('img');
              const img = new Image();
              img.src = reader.result as any;
              img.onload = () => {
                const ctx = canvas.getContext('2d');
                //原始图片宽度、高度
                const originImageWidth = img.width,
                  originImageHeight = img.height;
                //默认最大尺度的尺寸限制在(1920 * 1080)
                const maxWidth = 1920,
                  maxHeight = 1080,
                  ratio = maxWidth / maxHeight;
                //目标尺寸
                let targetWidth = originImageWidth,
                  targetHeight = originImageHeight;
                //当图片的宽度或者高度大于指定的最大宽度或者最大高度时,进行缩放图片
                if (originImageWidth > maxWidth || originImageHeight > maxHeight) {
                  //超过最大宽高比例
                  if (originImageWidth / originImageHeight > ratio) {
                    //宽度取最大宽度值maxWidth,缩放高度
                    targetWidth = maxWidth;
                    targetHeight = Math.round(maxWidth * (originImageHeight / originImageWidth));
                  } else {
                    //高度取最大高度值maxHeight,缩放宽度
                    targetHeight = maxHeight;
                    targetWidth = Math.round(maxHeight * (originImageWidth / originImageHeight));
                  }
                }
                // canvas对图片进行缩放
                canvas.width = targetWidth;
                canvas.height = targetHeight;
                // 清除画布
                ctx?.clearRect(0, 0, targetWidth, targetHeight);
                // 绘制图片
                ctx?.drawImage(img, 0, 0, targetWidth, targetHeight);
                // quality值越小,图像越模糊,默认图片质量为0.92
                const imageDataURL = canvas.toDataURL(file.type || 'image/jpeg', pictureQuality);
                // 去掉URL的头,并转换为byte
                const imageBytes = window.atob(imageDataURL.split(',')[1]);
                // 处理异常,将ascii码小于0的转换为大于0
                const arrayBuffer = new ArrayBuffer(imageBytes.length);
                const uint8Array = new Uint8Array(arrayBuffer);
                for (let i = 0; i < imageBytes.length; i++) {
                  uint8Array[i] = imageBytes.charCodeAt(i);
                }
                const mimeType = imageDataURL?.split(',')?.[0]?.match(/:(.*?);/)?.[1];
                const newFile = new File([uint8Array], file.name, {
                  type: mimeType || 'image/jpeg'
                });
                console.log(
                  'after compress, the file size is : ',
                  (newFile.size / 1024 / 1024).toFixed(2) + 'M'
                );
                console.log('after compress file: ', newFile);
                resolve(newFile);
              };
            };
            reader.onerror = () => {
              return file;
            };
          })
            .then(res => {
              return res;
            })
            .catch(() => {
              return file;
            });
        } catch (e) {
          //压缩出错,直接返回原file对象
          return file;
        }
      }
    } else {
      //不需要压缩,直接返回原file对象
      return file;
    }
  } else {
    //非图片文件,不进行压缩,直接返回原file对象
    return file;
  }
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用canvas进行图片压缩(前端图片压缩核心处理) 的相关文章

  • 如何从 JavaScript 中计算 HTML 表格的渲染高度?

    调整窗口大小时 我需要知道表格有多大 以便我可以动态地很好地适应中间的所有其他内容 表格高度仅取决于动态加载的内容 如何在 JavaScript 中计算表格的渲染高度 您可以使用element offsetHeight https deve
  • Javascript 与 Python 关于 Python 'map()' 函数的比较

    Python中有一个函数叫做map这可以让你去 map someFunction x y z 并继续应用该功能的列表 是否有与此功能等效的 JavaScript 我现在刚刚学习Python 虽然我被告知javascript是函数式语言 但我
  • 您可以使用 JavaScript 触发自定义 HTML5 表单错误吗?

    如果我有一个像这样的输入
  • 检查 DOM 元素是否为复选框

    如何检查给定的 DOM 元素是否为复选框 设想 我有一组文本框和复选框 其中的值是动态分配的 我没有办法识别 DOM 元素是复选框还是文本框 只使用普通的 javascript 你就可以做到 if el type el type check
  • Google 饼图未显示所有数据行

    我正在尝试绘制人口与国家名称的关系图 我发现 Google 可视化库仅渲染前几个 实际上数字似乎是随机的 具体取决于我使用的数据 有时添加 其他 条目 但它没有t 实际上具有其余条目的值 Example 1 With all countri
  • jQuery 的 css() 在应用于滚动事件时滞后

    我正在尝试实现一个简单的 固定标题 表 我知道这在理论上只能用 CSS 来完成 但是当涉及到 OSX Lion 及其消失的滚动条时 它效果不佳 所以我用 jQuery 来做 方法很简单 只有1 5行代码 inbox scroll funct
  • 在 Angular2 项目中集成 Treant-js

    我正在尝试在 Angular2 项目中使用 treant js 但我正在努力解决如何正确集成它的问题 我有一个工作正常的 JavaScript HTML 示例 我正在尝试在 Angular2 中工作 我创建了一个组件 从 npm 添加了 t
  • 光滑的轮播缓动示例

    我正在使用 Slick Carousel http kenwheeler github io slick http kenwheeler github io slick 但不知道如何合并不同的幻灯片切换 有人有例子可以分享吗 这是我目前拥有
  • 专用网络:web3.eth.getAccounts() 始终发送空数组

    我正在运行一个私人以太坊网络 我确实用https aws amazon com blockchain templates 整个设置已经完成 AWS 上的设置看起来正确 现在 我正在尝试创建帐户并检索所有这些帐户 为此 我使用以下方法 Web
  • Chrome Javascript 调试器暂停时不会重新加载页面

    有时 当我在 Chrome 中调试某些 javascript 并且暂停了 javascript 时 如果我尝试重新加载页面 chrome 只会 继续 调试器 单步执行到下一个断点 似乎没有任何方法可以强制 javascript 完全停止运行
  • Web SQL 数据库 + Javascript 循环

    我正在尝试解决这个问题 但我自己似乎无法解决 我正在使用 Web SQL DB 但无法让循环正常使用它 I use for var i 0 i lt numberofArticles 1 i db transaction function
  • Javascript 选择 onchange='this.form.submit()'

    我有一个带有选择和一些文本输入的表单 我希望在更改选择时提交表单 使用以下方法可以正常工作 onchange this form submit 但是 如果表单还包含提交按钮 则当选择更改时 表单不会提交 我猜有某种冲突 我在这里有什么选择
  • 如何在 angularjs 中修剪()字符串?

    有角度特定的方法吗 如果没有 我应该使用内置的jquery 来做到这一点吗 如果我应该使用内置的jquery 如何在不使用 的情况下访问trim 函数 或者这是必要的 编辑 是的 我知道 str trim 对不起 我需要这个才能在 IE 8
  • 理论上防止 WebSocket 中第一个收到的消息丢失

    服务器端代码发送消息立即地连接打开后 它向客户端发送初始配置 问候语 以下代码是在客户端 var sock new WebSocket url sock addEventListener error processError sock ad
  • ThreeJS无法加载Json文件

    首先 我已经读过这个问题 https stackoverflow com questions 17201888 three js exporter export object not working with jsonloader r58没
  • 使用 jQuery Tablesorter 操作后如何恢复当前页面?

    我正在使用 tablesorter 但无法找到有关插件 tablesorter 寻呼机的任何文档 问题是我有一个显示一些数据的表 并且在每一行中都有一个删除链接 该链接附加了要删除的元素的唯一标识符 显然 是否可以保存我正在删除的页面 然后
  • Dojo/on 和捕获阶段

    有没有办法用 dojo on 在捕获阶段 而不是冒泡阶段 触发事件 我最终在这里寻找有关 on 的前身 dojo connect 的信息 就其价值而言 dojo connect 似乎不支持捕获阶段的事件侦听器 它的工作原理是将事件处理程序作
  • 如何根据所需表单输入的值更改 CSS 样式

    我想知道如何编写 javascript 来改变所需的表单元素的样式 如果它们有价值的话就改变它们 我想要做的是当所需的文本字段为空时 在它们周围有一个彩色边框 并在它们有值时删除边框样式 我想做的是编写一个 javascript 函数来检查
  • Serviceworker Bug event.respondWith

    我的 serviceworker 的逻辑是 当发生获取事件时 它首先获取包含一些布尔值 而不是 event request url 的端点 并根据我正在调用的值检查该值event respondWith 对于当前的获取事件 我正在提供来自缓
  • 使用 Lodash 将对象键转换为具有键值数量的数组[重复]

    这个问题在这里已经有答案了 我有一个产品对象 products bread 1 milk 2 cheese 2 chicken 1 我想要一个包含产品名称的数组 如下所示 products bread milk milk cheese ch

随机推荐

  • QT风格(QStyle):绘制控件风格设置--QStyleOption

    QStyleOption是风格的设置类 定义了最基本的绘制控件所需的信息 绘制不同控件时 控件所使用的设置类继承QStyleOption 且OptionType值不同 如绘制按钮的风格设置类QStyleOptionButton继承QStyl
  • 记录es几个问题,增删改查,索引创建

    一 es版本 依赖
  • Echarts开发人物关系网络图

    引言 人物关系可视化是将人与人之之间通过某属性进行连接而形成的关系网络 通过可视化技术展现出来 而baidu的Echarts是一款非常敏捷 迅速 酷炫的js可视化工具 1 Echarts介绍 ECharts 一个纯 Javascript 的
  • 2021年连云港高考成绩查询,2021年连云港高考状元是谁分数多少分,历年连云港高考状元名单...

    2020年连云港一年一度的高考考试已经结束 今年连云港高考状元是谁呢 连云港高考状元出自哪个高中学校 文理科分数是多少分 一起来了解 一 2020年连云港高考状元名单资料 2020年连云港高考状元名单和学校相关信息 截至目前发文时间 官方暂
  • [学opencv]opencv Mat类型初始化,遍历,赋值

    1 opencv Mat类型定义 cv Mat a cv Size w h CV 8UC1 单通道 cv Mat b cv Mat cv Size w h CV 8UC3 3通道每个矩阵元素包含3个uchar值 对于维数较小的Mat类型 直
  • ARM Linux下安装CH341串口驱动

    在arm Linux环境下安装CH341串口驱动需要单独编译串口的驱动 本人编译环境Ubuntu 14 04 gcc编译工具arm linux gnueabihf gcc 1 代码检查 查看内核目录下 kernel drivers usb
  • Python中的logging模块解析

    前言 在自动化测试中 为了定位问题 调试框架代码 需要使用日志模块 今天我们重点讲解Python中的logging模块 在学习使用logging模块前 我们先要了解logging模块的四大天王 logger handler filter f
  • 《认识k8s》学习笔记Day01

    一 传统的部署方式 将三个应用部署到一台机器上 如果其中一台机器崩溃 会导致其他的机器受到影响 严重的会导致其他应用下线并不安全 二 虚拟化的部署方式 在物理机上开通几个虚拟机 将应用部署到虚拟机上 就算某个应用崩溃了 也只在这个虚拟机内崩
  • 怎样用计算机绘制幂函数图像,几何画板如何画幂函数的图像

    在学习了一些基本初等函数后 会接触 幂函数 概念 其实幂函数并不是陌生的 之前学过的依次函数 二次函数和反比例函数都是幂函数 幂函数其实同指数函数 对数函数一样 都是函数中的一类特殊函数 利用几何画板探究幂函数的性质 可以克服黑板作图的不精
  • 顺序表的基本操作(1)——插入操作

    顺序表的插入运算 线性表的插入运算是指在表的第i 1 i n 1 个位置 插入一个新元素x 使长度为n的线性表 a1 ai 1 ai an 变成长度为n 1的线性表 a1 ai 1 x ai 1 an 算法思想 用顺序表作为线性表的存储结构
  • 黄金矿工--回溯算法

    LeetCode 1219 黄金矿工 你要开发一座金矿 地质勘测学家已经探明了这座金矿中的资源分布 并用大小为 m n 的网格 grid 进行了标注 每个单元格中的整数就表示这一单元格中的黄金数量 如果该单元格是空的 那么就是 0 为了使收
  • CloudQuery到底是一款什么样的数据库管理工具

    前言 随着时代和企业的发展 单一或少数的数据库 繁杂错乱的操作工具已无法满足开发者对数据获取和操作的新要求 那么 有没有一款工具可以将所有数据库归纳到一个平台中 有没有办法让开发者操作数据更加高效便捷 我们曾在市面上找了很久 但仍没有找到一
  • pytorch:把图片数据转化成tensor

    摘要 在图像识别当中 一般步骤是先读取图片 然后把图片数据转化成tensor格式 再输送到网络中去 本文将介绍如何把图片转换成tensor 一 数据转换 把图片转成成torch的tensor数据 一般采用函数 torchvision tra
  • 让人抓狂的 URL 重定向的 Cookie 问题

    想象下面两行伪代码 1 setCookie 2 redirect new web url 首先设置一个Cookie 然后重定向到另外一个网址 这个网址跟当前网站的域名不同 在多数情况下这两行代码执行毫无问题 cookie 正确保存到浏览器
  • SHELL 基础 入门(三) Bash 快捷键 命令执行顺序,详解通配符

    目录 Bash 常用快捷键 输入输出重定向 lt lt 用法 输出重定向 命令执行顺序 分号 通配符 传统通配符 常用字符 强调 生成序列 Bash 常用快捷键 Ctrl A 把光标移动到命令行开头 Ctrl E 把光标移动到命令行尾 Ct
  • 国产FPGA芯片,机遇与挑战并存

    FPGA是可以先购买再设计的 万能 芯片 FPGA Field Programmable Gate Array 现场可编程门阵列 是在硅片上预先设计实现的具有可编程特性的集成电路 它能够按照设计人员的需求配置为指定的电路结构 让客户不必依赖
  • 数据结构中缀表达式转换为后缀表达式并求值,pta试题,小白心酸史

    数据结构中缀表达式转换为后缀表达式并求值 1 中缀表达式转换为后缀表达式并求值 100分 把题目给出中缀表达式转换为后缀表达式输出 并求后缀表达式的值 为简单起见 我们约定 1 输入的中缀表达式一定是合法的 并且只含数字 四种运算符 和小括
  • 我的opencv3.1+vs2015配置

    opencv下载地址 www opencv org 下载opencv3 1版本 其实是个压缩文件zip 然后解压 解压文件说明 build 里是各平台的jar dll sources 是源文件 头文件 框架等等 设置环境变量 右键我的电脑
  • R语言介绍

    1 R的统计计算和绘图功能十分强大 2 R是一种区分大小写的解释型语言 R的赋值符号是 lt 而不是传统的 号 3 x lt rnorm 5 表示了一个名为x的向量对象 它包含5个来自标准正态分布的随机偏差 4 注释是有 开头 再 之后的任
  • 使用canvas进行图片压缩(前端图片压缩核心处理)

    一 原理 实际上就是利用canvas进行重新绘制 1 先将图片的file文件转成baseURL 2 创建一个image标签去接收文件获取图片的宽高和比例 3 创建canvas画布设置画布的大小 4 将图片绘制到canvas上面 5 对can