当前位置: 首页 > news >正文

后端|压缩Base64图片的两种方式

        Base64是一种将二进制数据编码为ASCII字符串的方法。它通过将3个字节的二进制数据转换为4个可打印字符的ASCII字符,从而将二进制数据转换为可传输的文本格式。Base64编码常用于传输图片或音频文件。Base64编码可以保证数据在传输过程中不丢失,同时可以避免某些系统不支持二进制数据的问题。

        但是Base64转换成图片之前,如何压缩目标图片的大小呢?本文提供两种方式。

方法一:按尺寸压缩(不保证图片质量)

/*** 去掉Base64图片数据的前缀** @param base64Str 含前缀的Base64字符串* @return 不含前缀的Base64字符串*/private static String removeBase64Prefix(String base64Str) {// 使用正则表达式去掉"data:image/\w+;base64,"前缀Pattern pattern = Pattern.compile("^data:image/\\w+;base64,");Matcher matcher = pattern.matcher(base64Str);return matcher.replaceFirst("");}/*** 添加Base64图片数据的前缀** @param base64Str 不含或含其他前缀的Base64字符串* @param prefix 想要添加的Base64前缀,默认为"data:image/png;base64,"* @return 含指定前缀的Base64字符串*/public static String addBase64Prefix(String base64Str, String prefix) {// 检查是否已存在指定的前缀,如果有,则直接返回if (base64Str.startsWith(prefix)) {return base64Str;}return prefix + base64Str;}/*** 压缩base64编码至200K以内** @param base64Img* @return*/public static String resizeImageTo200K(String base64Img) {try {byte[] bytes1 =  Base64.getDecoder().decode(removeBase64Prefix(base64Img));System.out.println( bytes1.length);InputStream stream = new ByteArrayInputStream(bytes1);BufferedImage src = ImageIO.read(stream);// 压缩的尺寸BufferedImage output = output=Thumbnails.of(src).size(640, 480).asBufferedImage();String base64 = imageToBase64(output);double minScalingFactor = 0.7; // 设置最小缩放因子if (base64.length() - base64.length() / 8 * 2 > 200000) {double scalingFactor = Math.max(minScalingFactor, 1 - (base64.length() / 200000));output = Thumbnails.of(output).scale(scalingFactor).asBufferedImage();base64 = imageToBase64(output);}return addBase64Prefix(base64, "data:image/png;base64,");} catch (Exception e) {return addBase64Prefix(base64Img, "data:image/png;base64,");}}// BufferedImage转换成base64,在这里需要设置图片格式,如下是png格式图片:public static String imageToBase64(BufferedImage bufferedImage) {ByteArrayOutputStream baos = new ByteArrayOutputStream();try {ImageIO.write(bufferedImage, "png", baos);} catch (IOException e) {}String str = new String(Base64.getEncoder().encode(baos.toByteArray()));return str;}}

方法二:等质量压缩

 /*** 压缩base64编码图片至目标大小附近,尽量保持图片质量** @param base64Img base64编码的图片字符串* @param targetSize 目标大小(例如:200KB)* @return 调整大小后的base64编码图片字符串*/public static String resizeImageToTargetSize(String base64Img, int targetSize) {try {String s = removeBase64Prefix(base64Img);byte[] imageBytes = Base64.getDecoder().decode(s);ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);BufferedImage src = ImageIO.read(inputStream);// 初始化压缩质量为最高,根据需要逐步降低float quality = 1.0f;float step = 0.1f;boolean compressMore = true;byte[] compressedBytes = null;while (compressMore) {ByteArrayOutputStream outputStream = new ByteArrayOutputStream();Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpeg");if (!writers.hasNext()) throw new IllegalStateException("No writers found");ImageWriter writer = writers.next();ImageWriteParam param = writer.getDefaultWriteParam();// 设置压缩质量param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);param.setCompressionQuality(quality);MemoryCacheImageOutputStream memStream = new MemoryCacheImageOutputStream(outputStream);writer.setOutput(memStream);IIOImage outputImage = new IIOImage(src, null, null);writer.write(null, outputImage, param);writer.dispose();compressedBytes = outputStream.toByteArray();int currentSize = compressedBytes.length;System.out.println("尝试质量: " + quality + ", 大小: " + currentSize);// 如果压缩后大小仍超过目标大小,降低质量继续尝试;否则停止循环if (currentSize > targetSize) {quality -= step;if (quality < 0.1f) { // 防止质量降得过低quality = 0.1f;}} else {compressMore = false;}}String base64Encoded = Base64.getEncoder().encodeToString(compressedBytes);return addBase64Prefix(base64Encoded, "data:image/png;base64,");} catch (Exception e) {return base64Img; // 如果压缩失败,返回原图}}

相关文章:

后端|压缩Base64图片的两种方式

Base64是一种将二进制数据编码为ASCII字符串的方法。它通过将3个字节的二进制数据转换为4个可打印字符的ASCII字符&#xff0c;从而将二进制数据转换为可传输的文本格式。Base64编码常用于传输图片或音频文件。Base64编码可以保证数据在传输过程中不丢失&#xff0c;同时可以避…...

HCIP认证笔记(单选题)

1、OSPF Hello报文中不包括:process ID 3、IS-IS路由的开销在narrow模式下路由的开销值取值范围是:1~63; 在wide模式下路由的开销取值范围为:1~16777215 4、attached-bit advertise never 命令可以使level-1设备不生成缺省路由; 5、OSPFv3报文封装在IPv6报文内,IPv…...

数据结构笔记-2、线性表

2.1、线性表的定义和基本操作 如有侵权请联系删除。 2.1.1、线性表的定义&#xff1a; ​ 线性表是具有相同数据类型的 n (n>0) 个数据元素的有限序列&#xff0c;其中 n 为表长&#xff0c;当 n 0 时线性表是一个空表。若用 L 命名线性表&#xff0c;则其一般表示为&am…...

Linux基础IO【II】真的很详细

目录 一.文件描述符 1.重新理解文件 1.推论 2.证明 2.理解文件描述符 1.文件描述符的分配规则 3.如何理解文件操作的本质&#xff1f; 4.输入重定向和输出重定向 1.原理 2.代码实现重定向 3.dup函数 ​编辑 4.命令行中实现重定向 二.关于缓冲区 1.现象 …...

【C++】模板及模板的特化

目录 一&#xff0c;模板 1&#xff0c;函数模板 什么是函数模板 函数模板原理 函数模板的实例化 推演(隐式)实例化 显示实例化 模板的参数的匹配原则 2&#xff0c;类模板 什么是类模板 类模板的实例化 二&#xff0c;模板的特化 1&#xff0c;类模板的特化 全特化…...

2001-2023年上市公司数字化转型测算数据(含原始数据+处理代码+计算结果)

2001-2023年上市公司数字化转型测算数据&#xff08;含原始数据处理代码计算结果&#xff09;&#xff08;吴非&#xff09; 1、时间&#xff1a;2001-2023年 2、来源&#xff1a;上市公司年报 3、指标:行业代码、行业名称、证券简称、是否发生ST或ST或PT、是否发生暂停上市…...

ICRA 2024:基于视觉触觉传感器的物体表⾯分类的Sim2Real双层适应⽅法

⼈们通常通过视觉来感知物体表⾯的性质&#xff0c;但有时需要通过触觉信息来补充或替代视觉信息。在机器⼈感知物体属性⽅⾯&#xff0c;基于视觉的触觉传感器是⽬前的最新技术&#xff0c;因为它们可以产⽣与表⾯接触的⾼分辨率 RGB 触觉图像。然⽽&#xff0c;这些图像需要⼤…...

代理模式(设计模式)

文章目录 静态代理动态代理代理模式的应用场景动态代理和静态代理的区别 代理模式就是给一个对象提供一个代理&#xff0c;并由代理对象控制对原对象的引用。它使得客户不能直接与真正的目标对象通信。代理对象是目标对象的代表&#xff0c;其他需要与这个目标对象打交道的操作…...

C++函数参数传递

C 函数传参 在C中&#xff0c;函数传递参数的方式主要有三种&#xff1a; 按值传递&#xff08;pass by value&#xff09;按引用传递&#xff08;pass by reference&#xff09;按指针传递&#xff08;pass by pointer&#xff09;。 比较与总结 按值传递&#xff1a;适用…...

软考初级网络管理员_09_网络单选题

1.下列Internet应用中对实时性要求最高的是()。 电子邮件 Web浏览 FTP文件传输 IP电话 2.在Internet中的大多数服务(如WWW、FTP等)都采用()模型。 星型 主机/终端 客户机/服务器 网状 3.子网掩码的作用是()。 可以用来寻找网关 可以区分IP和MAC 可以识别子网 可以…...

曲线拟合 | 二次B样条拟合曲线

B 样条曲线拟合实例&#xff1a;能平滑化曲线 1. 实例1 为MASS包中mcycle数据集。它测试了一系列模拟的交通车事故中&#xff0c;头部的加速度&#xff0c;以此来评估头盔的性能。times为撞击时间(ms)&#xff0c;accel为加速度&#xff08;g&#xff09;。首先导入数据&#…...

delphi FDMemTable1.SourceView遍历各行数据,取任意行数据无需Next移动指针了。TFDDatSView

for m : 0 to FDMemTable1.SourceView.Rows.Count - 1 do begin if FDMemTable_SP.SourceView.Rows.ItemsI[m].GetData(0) varNull then Continue; end; 9行7列的值。 FDMemTable1.Data.DataView.Rows.ItemsI[9].ValueI[7]; FDMemTable1.Table.Ro…...

为什么选择 ABBYY FineReader PDF ?

帮助用户们对PDF文件进行快速的编辑处理&#xff0c;同时也可以快速识别PDF文件里的文字内容&#xff0c;并且可以让用户们进行文本编辑&#xff0c;所以可以有效提升办公效率。 ABBYY-ABBYY Finereader 15 Win-安装包&#xff1a;https://souurl.cn/OY2L3m 高级转换功能 ABBY…...

php遇到的问题

1、 underfined at line 3 in xxx.php , 错误提示&#xff0c;注释这行代码 // error_reporting(DEBUG ? E_ALL : 0); 目录&#xff1a;config/config.php...

零基础入门学用Arduino 第二部分(二)

重要的内容写在前面&#xff1a; 该系列是以up主太极创客的零基础入门学用Arduino教程为基础制作的学习笔记。个人把这个教程学完之后&#xff0c;整体感觉是很好的&#xff0c;如果有条件的可以先学习一些相关课程&#xff0c;学起来会更加轻松&#xff0c;相关课程有数字电路…...

旅游行业电商平台:数字化转型的引擎与未来发展趋势

引言 旅游行业数字化转型的背景和重要性 随着信息技术的飞速发展&#xff0c;数字化转型成为各行业发展的必然趋势。旅游行业&#xff0c;作为一个高度依赖信息和服务的领域&#xff0c;数字化转型尤为重要。通过数字化手段&#xff0c;旅游行业能够实现资源的高效配置、服务的…...

Ubuntu 22.04安装 docker

安装过程和指令 # 1.升级 apt sudo apt update # 2.安装docker sudo apt install docker.io docker-compose # 3.将当前用户加入 docker组 sudo usermod -aG docker ${USER} # 4. 重启 # 5. 查看镜像 docker ps -a 或者 docker images # 6. 下载镜像 docker pull hello-world …...

【Gitlab】访问默认PostgreSQL数据库

本地访问PostgreSQL gitlab有可以直接访问内部PostgreSQL的命令 sudo gitlab-rails dbconsole # 或者 sudo gitlab-psql -d gitlabhq_production效果截图 常用SQL # 查看用户状态 select id,name,email,state,last_sign_in_at,updated_at,last_credential_check_at,last_act…...

乐鑫ESP32-C3芯片应用,启明云端WT32C3-S5模组:简化产品硬件设计

在数字化浪潮的推动下&#xff0c;物联网(IoT)正迅速成为连接现实世界与数字世界的桥梁。芯片作为智能设备的心脏&#xff0c;其重要性不言而喻。 乐鑫推出的ESP32-C3芯片以其卓越的性能和丰富的功能&#xff0c;为智能物联网领域带来了新的活力&#xff0c;我将带您深入了解这…...

算法刷题【二分法】

题目&#xff1a; 注意题目中说明了数据时非递减的&#xff0c;那么这样就存在二分性&#xff0c;能够实现logn的复杂度。二分法每次只能取寻找特定的某一个值&#xff0c;所以我们要分别求左端点和有端点。 分析第一组用例得到结果如下: 成功找到左端点8 由此可知&#xff0…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

Go语言多线程问题

打印零与奇偶数&#xff08;leetcode 1116&#xff09; 方法1&#xff1a;使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...