后端|压缩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字符,从而将二进制数据转换为可传输的文本格式。Base64编码常用于传输图片或音频文件。Base64编码可以保证数据在传输过程中不丢失,同时可以避…...

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、线性表的定义: 线性表是具有相同数据类型的 n (n>0) 个数据元素的有限序列,其中 n 为表长,当 n 0 时线性表是一个空表。若用 L 命名线性表,则其一般表示为&am…...

Linux基础IO【II】真的很详细
目录 一.文件描述符 1.重新理解文件 1.推论 2.证明 2.理解文件描述符 1.文件描述符的分配规则 3.如何理解文件操作的本质? 4.输入重定向和输出重定向 1.原理 2.代码实现重定向 3.dup函数 编辑 4.命令行中实现重定向 二.关于缓冲区 1.现象 …...

【C++】模板及模板的特化
目录 一,模板 1,函数模板 什么是函数模板 函数模板原理 函数模板的实例化 推演(隐式)实例化 显示实例化 模板的参数的匹配原则 2,类模板 什么是类模板 类模板的实例化 二,模板的特化 1,类模板的特化 全特化…...

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

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

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

C++函数参数传递
C 函数传参 在C中,函数传递参数的方式主要有三种: 按值传递(pass by value)按引用传递(pass by reference)按指针传递(pass by pointer)。 比较与总结 按值传递:适用…...

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

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

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文件进行快速的编辑处理,同时也可以快速识别PDF文件里的文字内容,并且可以让用户们进行文本编辑,所以可以有效提升办公效率。 ABBYY-ABBYY Finereader 15 Win-安装包:https://souurl.cn/OY2L3m 高级转换功能 ABBY…...

php遇到的问题
1、 underfined at line 3 in xxx.php , 错误提示,注释这行代码 // error_reporting(DEBUG ? E_ALL : 0); 目录:config/config.php...

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

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

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模组:简化产品硬件设计
在数字化浪潮的推动下,物联网(IoT)正迅速成为连接现实世界与数字世界的桥梁。芯片作为智能设备的心脏,其重要性不言而喻。 乐鑫推出的ESP32-C3芯片以其卓越的性能和丰富的功能,为智能物联网领域带来了新的活力,我将带您深入了解这…...

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

.NET MAUI Sqlite程序应用-数据库配置(一)
项目名称:Ownership(权籍信息采集) 一、安装 NuGet 包 安装 sqlite-net-pcl 安装 SQLitePCLRawEx.bundle_green 二、创建多个表及相关字段 Models\OwnershipItem.cs using SQLite;namespace Ownership.Models {public class fa_rural_base//基础数据…...

基于WPF技术的换热站智能监控系统09--封装水泵对象
1、添加用户控件 2、编写水泵UI 控件中用到了Viewbox控件,Viewbox控件是WPF中一个简单的缩放工具,它可以帮助你放大或缩小单个元素,同时保持其宽高比。通过样式和属性设置,你可以创建出既美观又功能丰富的用户界面。在实际开发中…...

GLM+vLLM 部署调用
GLMvLLM 部署调用 vLLM 简介 vLLM 框架是一个高效的大型语言模型(LLM)推理和部署服务系统,具备以下特性: 高效的内存管理:通过 PagedAttention 算法,vLLM 实现了对 KV 缓存的高效管理,减少了…...

leetcode 122 买卖股票的最佳时机||(动态规划解法)
题目分析 题目描述的已经十分清楚了,不做过多阐述 算法原理 状态表示 我们假设第i天的最大利润是dp[i] 我们来画一下状态机 有两个状态,买入后和卖出后,我们就可以使用两个dp表来解决问题 f[i]表示当天买入后的最大利润 g[i]表示当天卖出…...

C++设计模式---组合模式
1、介绍 组合模式(Composite)是一种结构型设计模式,也被称为部分-整体模式。它将复杂对象视为由多个简单对象(称为“组件”)组成的树形结构,这些组件能够共享相同的行为。每个组件都可能包含一个或多个子组…...

工厂方法模式(大话设计模式)C/C++版本
工厂方法模式 C 参考:https://www.cnblogs.com/Galesaur-wcy/p/15926711.html #include <iostream> #include <memory> using namespace std;// 运算类 class Operation { private:double _NumA;double _NumB;public:void SetNumA(){cout << &…...

[NCTF 2018]flask真香
打开题目后没有提示框,尝试扫描后也没有什么结果,猜想是ssti。所以尝试寻找ssti的注入点并判断模版。 模版判断方式: 在url地址中输入{7*7} 后发现不能识别执行。 尝试{{7*7}} ,执行成功,继续往下走注入{{7*7}},如果执…...

性能测试3【搬代码】
1.Linux服务器性能分析命令及详解 2.GarafanainfluxDB监控jmeter数据 3.GarafanaPrometheus监控服务器和数据库性能 4.性能瓶颈分析以及性能调优方案详解 一、无界面压测时, top load average:平均负载 htop 二、Garafana监控平台 传统项目:centosphpm…...

<tesseract><opencv><Python>基于python和opencv,使用ocr识别图片中的文本并进行替换
前言 本文是在python中,利用opencv处理图片,利用tesseractOCR来识别图片中的文本并进行替换的一种实现方法。 环境配置 系统:windows 平台:visual studio code 语言:python 库:pyqt5、opencv、tesseractOCR 代码介绍 本文程序功能实现,主要依赖于tesseractOCR这个库,…...

海南云亿商务咨询有限公司解锁抖音电商新纪元
在当今数字化浪潮中,抖音电商以其独特的魅力和强大的用户基础,迅速成为企业营销的新宠。海南云亿商务咨询有限公司,作为专注于抖音电商服务的领先企业,凭借专业的团队和丰富的经验,为众多企业提供了高效、精准的电商服…...