利用canvas压缩图片

前情提要

页面打印导出pdf文件的时候,图片大小会影响pdf文件大小。
为了减小pdf文件大小,需要将图片压缩一下。在只有图片地址的情况下,将图片压缩后显示,一开始用的browser-image-compression插件,这是js压缩,是个异步函数,速度有点慢,于是大佬提出用canvas压缩,一番百度之后,抽出了一个基础版。
不考虑代码优雅问题,只说能用就行。

1 代码

const imgUrl = "图片地址"
// 创建一个img标签
const img = new Image();
// 先给img加上onload方法,再设置src,防止设置onload的时候,已经加载好图片,onload就一直不触发
img.onload = () => {
    // 创建canvas  
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    // 设置canvas宽高,具体设置多少,后面解释
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;
    // 在canvas绘制前填充白色背景。
    // 遇到过白底的证件照压缩之后背景色变成了黑底,所以加一步填充背景色,不加也不影响压缩。
    ctx.fillStyle = "#fff";
    // 绘制图片
    ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
    // canvas转成图片地址,在这一步进行文件大小压缩,第二个参数设置图片质量,不写默认0.92,后面解释为什么写0.2
    const base64 = canvas.toDataURL('image/jpeg', 0.2);
    // 拿到新的图片地址后就能用来显示了,如何传给img标签大家就各显神通吧,后面会给一种方案
}
img.src = imgUrl;

示例图片:4000 × 2472 px 6.8M
页面显示:162 × 100 px
页面放大150%截图

2 canvas的宽高

canvas的宽高设置会影响最终图片的质量(模糊度和大小两方面)。
一般来说,原图尺寸 >> 页面显示的缩略图,原图几百几千px的宽高,放到页面上可能就被缩小到几十px,所以canvas大小可以从原图到缩略图,取值范围非常广。
(在toDataURL第二个参数默认0.92的情况下)
设置原图的尺寸,压缩效果有点差,但是图片比较清晰;
设置缩略图尺寸,压缩效果较好,但是图片模糊;
考虑到导出pdf之后,图片也就指甲盖大小,图片糊点就糊点吧,减小pdf大小最重要。但是我也不想让图片糊成马赛克,毕竟实际的缩略图尺寸真的太小了。所以我用的是缩略图宽高*4的尺寸

在这里插入图片描述

3 toDataURL第二个参数

toDataURL第二个参数设置也会影响最终图片的质量(模糊度和大小两方面)。
quality越大,图片的质量越高(图片越清晰,文件大小也越大),取值范围是0~1.0之间的double值。
网上看到一种说法是设置成0.2-0.5之间可以有效的压缩图片体积,减小pdf大小最重要,于是我用了0.2。
在这里插入图片描述

3 toDataURL第一个参数

第一个参数指定了图像的类型,例如"image/jpeg"或者"image/png",如果不指定,则默认使用"image/png"。
(网上查到)toDataURL第二个参数只适用于image/jpeg 或 image/webp类型的图片,他表示图像的显示质量,所以没管图片类型,toDataURL第一个参数都是"image/jpeg"
试了下"image/jpg"和"image/png",同一张图,原图尺寸的情况下,压缩文件变大了,如果使用缩略图尺寸,那倒是压缩了,毕竟图片是真变小了,但效果没有"image/jpeg"好。
(至于原因,有大佬补充吗?)

4 canvas.toDataURL()之后图片大小增加

如果将canvas设置为缩略图尺寸,应该是不会遇到标题中的情况的,毕竟图片尺寸小了那么多,文件大小应该不至于变大(个人见解)
但如果canvas使用原图尺寸,会比较容易遇上压缩之后文件还变大了的情况。
(网上看到)有种解释是文件体积过小反而会出现越压缩体积越大,这种情况可以设置一个体积阀门,小于某个尺寸(比如300K)的时候不进行压缩。
虽然最后没用上这个方案,但是测试的时候遇到过这个问题,所以记一下,如何根据图片url获取到图片大小。

5 本地验证遇到了跨域问题

测试canvas压缩图片可行性的时候,用的本地图片,结果遇到跨域问题
在这里插入图片描述在这里插入图片描述

Access to image at ‘file://xxx/xxx.jpg’ from origin ‘null’ has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome, https, chrome-untrusted.

4.1 查了下,可以改成使用图床。

随便找的免注册图床,https://wmimg.com/
这个图床的貌似有点问题,4.93M的图片上传之后变成6.8M,不过测试canvas压缩效果倒是比较明显。
这个图床也是免注册,https://postimages.org/
但是它自带的图片压缩功能,把4.93M的图片压成了33.8k,它都压那么好了我还能压什么。

4.2 然后,问题变成另一个报错。

在这里插入图片描述

Uncaught DOMException: Failed to execute ‘toDataURL’ on ‘HTMLCanvasElement’: Tainted canvases may not be exported.at img.onload ()

(网上查到)这是由于drawImage()向canvas导入的图片跨域而导致的。
这个好解决,给img加一下crossOrigin属性,打开跨域资源允许权限

const img = new Image();
img.crossOrigin = "Anonymous";

如果加上了crossOrigin = "Anonymous"依然存在跨域问题,那就换个图床。
因为存放图片地址的服务器也要开启跨域允许权限,改不了服务器,那就换个服务器吧。

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

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

相关文章

硬件产品设计过程:结构及硬件设计

目录 简介 设计管理问题 简介 之前也多次谈到硬件产品的设计分为多个过程,每个过程所涉及的内容也是完全不同的。 比如说: 后台、应用app层的开发;电子硬件设计;结构、ID设计;营销侧;生产管理侧;供应链管理侧等等。接下来就谈谈最近公司开发上的一些问题。 以往由于公…

docker nginx mysql redis

启动没有数据卷的nginx docker run -d -p 86:80 --name my-nginx nginx把/etc/nginx中的配置复制到宿主机 docker cp my-nginx:/etc/nginx /home/nginxlkl把/html 中的文件复制到宿主机 docker cp my-nginx:/etc/nginx /home/nginxlkl删除当前镜像 docker rm -f my-nginx重新起…

理解算法复杂度:时间复杂度详解

引言 在计算机科学中,算法复杂度是衡量算法效率的重要指标。时间复杂度和空间复杂度是算法复杂度的两个主要方面。在这篇博客中,我们将深入探讨时间复杂度,了解其定义、常见类型以及如何进行分析。 什么是时间复杂度? 时间复杂度…

【多语言独立站】什么是跨境电商独立站?||如何完成完善电商系统搭建

随着国际贸易的发展和互联网技术的不断提升,在跨境电商业务中,独立站是一个非常重要的组成部分。我们经常会听到的词语就是:「跨境电商独立站」、「外贸独立站」、「跨境独立站」、「电商独立站」等等。因此,我们可以发现独立站和…

【web前端HTML+CSS+JS】--- JS学习笔记03

一、JS介绍 可以在前端页面上进行逻辑处理,来解决表单的验证等问题,提升效率,直接在前端提示问题,减少服务器压力 应用1:可以做静态验证和动态验证(进行异步请求) 应用2:可以解析后…

Splunk Enterprise 任意文件读取漏洞(CVE-2024-36991)

文章目录 前言漏洞描述影响版本漏洞复现POC批量检测-nuclei脚本 修复建议 前言 Splunk Enterprise 是一款强大的机器数据管理和分析平台,能够实时收集、索引、搜索、分析和可视化来自各种数据源的日志和数据,帮助企业提升运营效率、增强安全性和优化业务…

【可视化还能免费做?!】数据安全不用愁,快来用这款免费可视化工具做智慧港口管理平台

在智慧港口的建设中,实现港口的统一调度是一项关键任务。山海鲸可视化,这款免费可视化工具,通过其卓越的功能和特色,为智慧港口的建设提供了强大的支持。从智慧港口的需求出发,结合船舶调度和货物转运的需求&#xff0…

「API取数」FDL获取金蝶云星空的单据数据

很多企业的ERP系统都在用金蝶云星空,金蝶云星空API是IT人员获取数据的重要来源, 常常用来生成定制化报表,进行数据分析,或是将金蝶云的数据与OA系统、BI工具集成。 通常情况下,IT人员需要使用Python、Java等语言编写脚…

Failed to get D-Bus connection: Operation not permitted

最近使用wsl安装了centOS7镜像,在系统中安装了docker服务,但是在执行systemctl start docker的时候遇到了:Failed to get D-Bus connection: Operation not permitted问题,查阅了很多资料都没有效果,最终找到了一种解决…

理解JS与多线程

理解JS与多线程 什么是四核四线程? 一个CPU有几个核它就可以跑多少个线程,四核四线程就说明这个CPU同一时间最多能够运行四个线程,四核八线程是使用了超线程技术,使得单个核像有两个核一样,速度比四核四线程有多提升。…

Q-Learning实战——找房间

介绍 样例来自A Painless Q-learning Tutorial (一个 Q-learning 算法的简明教程) 简单来说就是从某个房间开始,找到去目标房间的路径。 代码实现 import numpy as np from tqdm import tqdm, trangeroom_num 6 room_paths [(0, 4), (3, 4), (3, 1), (1, 5)…

exel带单位求和,统计元素个数

如果exel表格中,如果数据有单位,无法直接用 自动求和 直接求和。如下图所示,求和结果为0,显然不是我们想要的。 用下面的公式求和,单位不是“个”的时候记得替换单位。统计范围不是“C1:C7”也记得换一下啊&#xff01…

19_谷歌GoogLeNet(InceptionV1)深度学习图像分类算法

1.1 简介 GoogLeNet(有时也称为GoogleNet或Inception Net)是一种深度学习架构,由Google的研究团队在2014年提出,主要设计者为Christian Szegedy等人。这个模型是在当年的ImageNet大规模视觉识别挑战赛(ILSVRC&#xf…

实用性提升百分之一百!!!【ONLYOFFICE 8.1版本】全方位深度性能测评

目录 【ONLYOFFICE 8.1 版本】全方位深度性能测评 一、界面与用户体验 二、文字处理功能 表格处理功能 演示文稿功能 协作与共享功能 性能与稳定性 总结 【ONLYOFFICE 8.1 版本】全方位深度性能测评 在当今数字化办公的时代,办公软件的选择对于提高工作效率和…

【HTML入门】第四课 - 换行、分割横线和html的注释

这一小节,我们继续说HTML的入门知识,包括换行、横线分割以及注释(html的注释)。 目录 1 换行 2 分割横线 3 html注释 1 换行 html中分为块元素和行内元素。这一小节呢,先不说这些元素们,我们先说一下换…

安装Gradle

官网文档 https://gradle.org/ 腾讯下载镜像:https://mirrors.cloud.tencent.com/gradle/ 文档:https://docs.gradle.org/current/userguide/userguide.html 命令行文档:https://docs.gradle.org/current/userguide/command_line_interface.…

Python提取视频文案

Python提取视频文案 1、背景描述2、视频转音频3、音频转文字 1、背景描述 在多媒体应用中,视频是一个信息量巨大的载体。然而,有时我们需要从视频中提取语音并转换为文本,以用于文本分析和机器学习训练 其中主要涉及到两个过程:视…

String类(STL开始)

相信大家都知道STL在C中的重要性,作为其模板库中的一部分,包含了常见的数据结构和算法,是C的标准库 而我们今天要讲的String类(String底层是一个字符顺序数组的顺序表对象,可以归类为容器),其实…

MySQL安装时initializing database失败

问题页面: 解决方法: 1.勾选红框中的选项: 2.将下图红框中全部改为英文: 然后一路next就可以了。

洛谷 P3613 学习用map代替大大大数组的好题

题目链接:P3613 【深基15.例2】寄包柜 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目截图: 题意分析: 非常简单的存入和取出操作 唯一的 “难点” 在于 数组开不到 a[100007][100007],会暴内存 非常巧妙的引入 map 来解决…