Java图片与Base64互转:原理、实战与性能优化指南
1. 项目概述与核心价值最近在整理一个老项目的图片上传模块发现里面处理图片和Base64编码的逻辑写得有点乱各种字符串拼接和字节流操作混在一起维护起来相当头疼。这让我想起无论是处理前端传来的头像、生成带图片的邮件正文还是做简单的图片缓存Java 图片转Base64及Base64转图片这个看似基础的操作在实际开发中出现的频率其实非常高。但正因为基础很多开发者容易忽略其中的细节和陷阱比如编码格式选错导致图片损坏、内存溢出OOM或者性能问题。简单来说这个项目的核心就是实现图片二进制数据和Base64编码字符串之间的双向无损转换。Base64是一种用64个可打印字符A-Z, a-z, 0-9, , /来表示二进制数据的方法。它不是为了加密所以别用它来“加密”敏感图片而是为了在那些只支持文本传输的协议如HTTP、XML、JSON中安全地嵌入二进制数据。想象一下你要把一张图片通过JSON API传给前端直接塞二进制流肯定不行把它转成一长串Base64字符串就完美解决了。这个技能点不仅是Java面试八股文里的常客更是日常开发中的实用工具。无论是新手入门处理文件I/O还是老鸟优化系统性能都绕不开它。接下来我就结合自己踩过的坑和最佳实践把这套流程掰开揉碎了讲清楚。2. 核心原理与方案选型2.1 Base64编码解码原理浅析为什么是Base64直接传输二进制字节流不行吗问题在于很多网络协议或数据格式如早期的电子邮件SMTP、HTTP URL、XML/JSON文本是设计用来传输可打印的ASCII字符的。二进制数据中可能包含像换行符\n、结束符\0这类控制字符它们在这些协议中具有特殊含义直接传输会导致数据被错误解析而损坏。Base64的解决思路很巧妙它把每3个字节24位的二进制数据作为一个单元重新划分为4组每组6位。6位二进制数的范围是0-63正好对应64个可打印字符这就是“Base64”名字的由来。这样任何二进制数据都能被“翻译”成纯文本。如果原始数据字节数不是3的倍数会用等号进行填充确保输出字符串长度总是4的倍数。在Java中我们主要和图片的字节数组byte[]打交道。图片转Base64本质上是将图片文件读入为byte[]然后对这个字节数组进行Base64编码。反之Base64转图片则是将Base64字符串解码为byte[]再将这个字节数组写入图片文件或加载到内存图像对象中。2.2 Java中的Base64工具选型Java历史上处理Base64有点“折腾”但现在已经非常统一和强大了。我们主要关注java.util.Base64这个从Java 8开始提供的官方工具类。它完全取代了之前各种第三方库如Apache Commons Codec或自己手写的Base64工具类性能更好API更标准。Base64类内部提供了三种编码器/解码器对应不同场景基本Basic使用标准的Base64字母表A-Z, a-z, 0-9, , /编码后的字符串不包含换行符。这是最常用的。URL安全URL and Filename Safe将标准中的和/分别替换为-和_同时去掉填充符。这样编码出来的字符串可以直接放在URL或文件名里不会被误解析。MIME使用基本字母表但每76个字符插入一个换行符\r\n符合MIME格式规范如电子邮件。对于图片处理我们最常用的是基本编码器。但如果生成的Base64字符串需要嵌入到URL或前端img src标签的data URL中并且其中包含或/可能导致解析问题时可以考虑使用URL安全编码器。注意绝对不要使用sun.misc.BASE64Encoder等内部API它们并非Java标准API在不同JDK版本中可能不存在或行为不一致有严重的可移植性风险。3. 图片转Base64编码实战与细节把一张图片变成Base64字符串听起来就是“读文件转编码”但每一步都有需要注意的地方。3.1 标准编码流程与代码实现最直接的方式是使用Files.readAllBytes一次性读取图片文件然后用Base64.getEncoder()进行编码。这种方法代码简洁适用于中小图片。import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; public class ImageToBase64 { public static String encodeFileToBase64(String filePath) throws Exception { // 1. 将图片文件全部读入字节数组 byte[] fileContent Files.readAllBytes(Paths.get(filePath)); // 2. 使用基本编码器进行Base64编码 String encodedString Base64.getEncoder().encodeToString(fileContent); return encodedString; } }调用示例String base64Str encodeFileToBase64(“/path/to/your/image.jpg”);这行代码生成的字符串就是图片的完整Base64表示。你可以把它存入数据库的TEXT字段或者作为JSON响应的一部分发送给前端。3.2 处理大文件与内存优化上面的Files.readAllBytes方法虽然简单但它会将整个文件内容加载到堆内存中。对于一张10MB的图片就会瞬间占用10MB的堆空间。如果并发处理多张大图极易引发OutOfMemoryError: Java heap space。对于大图片我们必须采用流式处理Streaming避免一次性占用过多内存。思路是使用Base64.getEncoder().wrap()方法它返回一个OutputStream我们可以将文件输入流FileInputStream的内容通过这个包装流进行编码并直接写入到目标如ByteArrayOutputStream或网络输出流。import java.io.*; import java.util.Base64; public class ImageToBase64Stream { public static String encodeFileToBase64Stream(String filePath) throws Exception { try (FileInputStream fileInputStream new FileInputStream(filePath); ByteArrayOutputStream byteArrayOutputStream new ByteArrayOutputStream()) { // 用Base64编码器包装字节数组输出流 OutputStream base64OutputStream Base64.getEncoder().wrap(byteArrayOutputStream); // 缓冲区读写避免一次性加载 byte[] buffer new byte[4096]; // 4KB缓冲区 int bytesRead; while ((bytesRead fileInputStream.read(buffer)) ! -1) { base64OutputStream.write(buffer, 0, bytesRead); } // 重要关闭包装流确保编码完成并写入底层流 base64OutputStream.close(); // ByteArrayOutputStream中已包含编码后的字节转为字符串 return byteArrayOutputStream.toString(“UTF-8”); } } }这段代码通过4KB的缓冲区循环读写无论文件多大内存占用都相对恒定安全得多。3.3 生成Data URL格式前端显示图片时经常用到Data URL。它的格式是data:[mediatype][;base64],data。我们需要在Base64字符串前拼接上图片的MIME类型。import java.nio.file.Files; import java.nio.file.Path; import java.util.Base64; public class ImageToDataURL { public static String encodeFileToDataURL(String filePath) throws Exception { Path path Paths.get(filePath); String fileName path.getFileName().toString(); // 根据文件扩展名简单判断MIME类型实际项目建议用Files.probeContentType或第三方库 String mimeType “image/jpeg”; // 默认 if (fileName.toLowerCase().endsWith(“.png”)) { mimeType “image/png”; } else if (fileName.toLowerCase().endsWith(“.gif”)) { mimeType “image/gif”; } // ... 其他格式判断 byte[] fileContent Files.readAllBytes(path); String base64 Base64.getEncoder().encodeToString(fileContent); // 拼接成Data URL return “data:” mimeType “;base64,” base64; } }生成的字符串可以直接用于HTMLimg src“data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD...”。但要注意Data URL会显著增加HTML或CSS文件大小且不会被浏览器单独缓存仅适用于小图标或内联图片。实操心得在编码前最好能验证一下读入的字节确实是有效的图片。一个简单的做法是尝试用ImageIO.read(new ByteArrayInputStream(bytes))如果返回null则说明字节数据可能已损坏或不是支持的图片格式。这能在早期发现问题避免存储或传输无效的Base64字符串。4. Base64转图片解码与输出收到Base64字符串后我们需要将其还原成图片。这个过程是编码的逆过程但输出目标可以是文件、字节数组甚至是内存中的BufferedImage对象。4.1 解码为图片文件这是最常见的需求比如用户上传了Base64格式的头像我们需要保存为服务器上的图片文件。import java.io.FileOutputStream; import java.io.IOException; import java.util.Base64; import java.nio.file.Files; import java.nio.file.Paths; public class Base64ToImage { public static void decodeBase64ToFile(String base64Image, String outputFilePath) throws Exception { // 1. 获取基本解码器 Base64.Decoder decoder Base64.getDecoder(); // 2. 解码Base64字符串为字节数组 byte[] imageBytes decoder.decode(base64Image); // 3. 将字节数组写入目标文件 Files.write(Paths.get(outputFilePath), imageBytes); } }如果Base64字符串包含了Data URL前缀如data:image/png;base64,我们需要先把这个前缀去掉只解码逗号之后的部分。public static void decodeDataURLToFile(String dataUrl, String outputFilePath) throws Exception { // 分离MIME类型和Base64数据 String[] parts dataUrl.split(“,”); if (parts.length ! 2) { throw new IllegalArgumentException(“Invalid Data URL format”); } String base64Data parts[1]; Base64.Decoder decoder Base64.getDecoder(); byte[] imageBytes decoder.decode(base64Data); Files.write(Paths.get(outputFilePath), imageBytes); }4.2 解码为内存中的BufferedImage对象有时我们不需要保存文件而是想直接对图片进行操作如缩放、裁剪、添加水印等。这就需要将Base64解码为Java能直接操作的BufferedImage。import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.util.Base64; public class Base64ToBufferedImage { public static BufferedImage decodeBase64ToBufferedImage(String base64Image) throws Exception { Base64.Decoder decoder Base64.getDecoder(); byte[] imageBytes decoder.decode(base64Image); // 使用ByteArrayInputStream和ImageIO读取为BufferedImage try (ByteArrayInputStream bis new ByteArrayInputStream(imageBytes)) { BufferedImage image ImageIO.read(bis); if (image null) { throw new IllegalArgumentException(“Could not decode image from bytes. Invalid format?”); } return image; } } }拿到BufferedImage后你就可以使用Java2D API进行各种图像处理了。4.3 流式解码处理大字符串和编码一样如果Base64字符串非常长对应大图片直接decoder.decode(string)会一次性生成巨大的字节数组。我们可以使用Base64.getDecoder().wrap(InputStream)进行流式解码。import java.io.*; import java.util.Base64; public class Base64ToImageStream { public static void decodeBase64ToFileStream(String base64Image, String outputFilePath) throws Exception { // 将Base64字符串转换为字节输入流这里简化了大字符串来源可能是网络流 ByteArrayInputStream base64InputStream new ByteArrayInputStream(base64Image.getBytes(“UTF-8”)); try (InputStream decodedInputStream Base64.getDecoder().wrap(base64InputStream); FileOutputStream fileOutputStream new FileOutputStream(outputFilePath)) { byte[] buffer new byte[4096]; int bytesRead; while ((bytesRead decodedInputStream.read(buffer)) ! -1) { fileOutputStream.write(buffer, 0, bytesRead); } } } }这种方式特别适合处理来自网络流或超大字符串的Base64数据内存友好。5. 性能优化、常见问题与排查实录在实际项目中把这些基础功能用对、用好、用稳才是关键。下面分享一些性能优化的思路和踩坑记录。5.1 性能考量与最佳实践内存 vs 速度的权衡对于小于1MB的图片使用Files.readAllBytesencodeToString最简单快捷代码可读性高。对于大于1MB或并发处理的场景务必使用流式wrap方式这是避免OOM的底线。缓存编码结果如果同一张图片如系统默认头像、静态Logo需要被多次转换为Base64例如在列表接口中返回不要每次都从磁盘读取并编码。可以在应用启动时或首次使用时编码并缓存结果放在内存或分布式缓存中后续直接使用缓存字符串。选择合适的编码器99%的情况用Base64.getEncoder()就够了。只有当你明确知道生成的字符串要放入URL或文件名且担心和/字符时才使用Base64.getUrlEncoder().withoutPadding()withoutPadding可去掉末尾的。关闭资源使用try-with-resources语句确保InputStream、OutputStream被正确关闭这是防止资源泄漏的好习惯。5.2 典型问题排查表下面这个表格整理了几个最常见的问题、原因和解决方案你可以像查手册一样快速定位。问题现象可能原因排查步骤与解决方案解码后图片损坏无法打开1. Base64字符串被截断或传输中出错。2. 字符串包含非法字符如空格、换行。3. 包含了Data URL前缀但未去除。1. 检查字符串长度Base64字符串长度应是4的倍数填充后。2. 在解码前用base64Str base64Str.trim().replaceAll(“\\s”, “”)去除所有空白字符。3. 确认是否需去除data:image/xxx;base64,前缀。解码抛出IllegalArgumentException: Illegal base64 characterBase64字符串中包含非字母表字符如\n,\r, 空格或字符集不匹配。1. 同上先进行trim()和替换空白字符。2. 确保传输/存储过程没有引入额外编码如URL编码。如果是URL安全编码请使用Base64.getUrlDecoder()。编码后前端显示为破碎图片1. 生成的Data URL的MIME类型与实际图片格式不符。2. 编码过程本身出错字节数据已损坏。1. 核对文件扩展名与MIME类型jpg-image/jpeg, png-image/png。2. 将解码回的字节数组保存为文件看是否能正常打开以确定编码环节是否出错。处理大图时程序内存溢出OOM使用了readAllBytes或decode(String)一次性加载全部数据。必须改造为流式处理使用Base64.getEncoder().wrap()或Base64.getDecoder().wrap()配合缓冲区循环读写。编码字符串中有换行错误地使用了MIME编码器Base64.getMimeEncoder它默认每76字符换行。明确需求。如果不需要换行请使用Base64.getEncoder()。如果需要换行但长度不同可使用Base64.getMimeEncoder(lineLength, separator)自定义。5.3 一个综合工具类的实现最后分享一个我项目中常用的工具类它封装了上述大部分最佳实践并处理了Data URL和URL安全编码的情况。import java.io.*; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; import java.util.regex.Pattern; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; public class Base64ImageUtil { private static final Pattern DATA_URL_PATTERN Pattern.compile(“^data:image/[a-z];base64,”, Pattern.CASE_INSENSITIVE); /** * 图片文件转Base64字符串标准 */ public static String imageFileToBase64(String filePath) throws IOException { byte[] bytes Files.readAllBytes(Paths.get(filePath)); return Base64.getEncoder().encodeToString(bytes); } /** * 图片文件转Data URL */ public static String imageFileToDataURL(String filePath) throws IOException { String fileName Paths.get(filePath).getFileName().toString().toLowerCase(); String mimeType; if (fileName.endsWith(“.png”)) mimeType “image/png”; else if (fileName.endsWith(“.gif”)) mimeType “image/gif”; else if (fileName.endsWith(“.bmp”)) mimeType “image/bmp”; else mimeType “image/jpeg”; // 默认jpeg String base64 imageFileToBase64(filePath); return String.format(“data:%s;base64,%s”, mimeType, base64); } /** * Base64字符串转图片文件自动处理Data URL */ public static void base64ToImageFile(String base64Str, String outputPath) throws IOException { // 清理字符串去空白处理Data URL前缀 String cleanBase64 cleanBase64String(base64Str); byte[] bytes Base64.getDecoder().decode(cleanBase64); Files.write(Paths.get(outputPath), bytes); } /** * Base64字符串转BufferedImage自动处理Data URL */ public static BufferedImage base64ToBufferedImage(String base64Str) throws IOException { String cleanBase64 cleanBase64String(base64Str); byte[] bytes Base64.getDecoder().decode(cleanBase64); try (ByteArrayInputStream bis new ByteArrayInputStream(bytes)) { BufferedImage image ImageIO.read(bis); if (image null) { throw new IOException(“Failed to decode image from Base64 string. Invalid image data or format.”); } return image; } } /** * 清理Base64字符串去除Data URL前缀和所有空白字符 */ private static String cleanBase64String(String str) { // 去除Data URL前缀 String cleaned DATA_URL_PATTERN.matcher(str).replaceFirst(“”); // 去除所有空白字符空格、换行、制表符等 cleaned cleaned.replaceAll(“\\s”, “”); return cleaned; } /** * 生成URL安全的Base64字符串无填充 */ public static String toUrlSafeBase64(byte[] bytes) { return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes); } /** * 解码URL安全的Base64字符串 */ public static byte[] fromUrlSafeBase64(String str) { return Base64.getUrlDecoder().decode(str); } }这个工具类提供了开箱即用的方法并内置了字符串清理逻辑能应对多数常见场景。记住对于生产环境中的大图片处理仍需将imageFileToBase64和base64ToImageFile方法改造成流式版本以确保稳健性。

相关新闻

河北省沧州市四层自建房,建房前期空间方案规划,两跑楼梯并排井道家用电梯落地案例

河北省沧州市四层自建房,建房前期空间方案规划,两跑楼梯并排井道家用电梯落地案例

一、项目背景与用户需求本案例项目位于河北省沧州市,房屋为四层自建住宅。业主处于房屋前期设计阶段,一直被家用电梯井道预留尺寸、位置布局问题困扰。业主自行构思多种尺寸方案,联合设计师反复研讨,始终没能找到兼顾实用性与空间…

2026/10/2 23:52:30 阅读更多 →
进程管道通讯-伪终端方式

进程管道通讯-伪终端方式

传统CreateProcess传递StdIN StdOUT 管道方式存在进程输出不能及时刷管道问题导致ReadFile阻塞,传统解决方法是子进程强制进行fflush(stdout), 如果不能改变子进程,就没办法了从win10开始 windows支持伪终端,可以完全模拟终端管道的行为&…

2026/10/10 0:34:40 阅读更多 →
计算机自学路线:从零基础到进阶的完整指南

计算机自学路线:从零基础到进阶的完整指南

1. 计算机课程自学路线规划作为一名在IT行业摸爬滚打十年的老程序员,我经常被问到"如何系统学习计算机知识"。市面上课程琳琅满目,但缺乏体系化的学习路径往往让初学者陷入"东一榔头西一棒子"的困境。这里分享我总结的计算机课程学习…

2026/10/3 11:45:51 阅读更多 →

最新新闻

头歌MySQL实训全关卡答案解析与避坑指南

头歌MySQL实训全关卡答案解析与避坑指南

简介:这是一份头歌MySQL数据库实训的答案整理文档,面向正在完成头歌平台实训作业的学生,也适合需要系统回顾MySQL核心操作的初学者。文档以PDF格式提供,共1个文件,压缩包大小433KB,配有目录结构&#xff0c…

2026/10/12 0:30:14 阅读更多 →
OpenClaw 下一代 AI 助手框架:让 AI 拥有记忆和工具,TaoToken 统一 Key 接入实战

OpenClaw 下一代 AI 助手框架:让 AI 拥有记忆和工具,TaoToken 统一 Key 接入实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 0:30:14 阅读更多 →
身份证识别OCR实战:从图像预处理到字段解析的完整流程

身份证识别OCR实战:从图像预处理到字段解析的完整流程

简介:这是一份面向图像识别与OCR入门者的身份证识别项目实践资源,聚焦从身份证图片中自动提取身份证号及其他字段的完整实现。项目基于百度开源的PaddleOCR,针对中文识别效果做了优化,并编译了Windows可执行版本,可通过…

2026/10/12 0:30:14 阅读更多 →
Hyperf 中使用 Elasticsearch:协程化客户端封装与连接池实战指南

Hyperf 中使用 Elasticsearch:协程化客户端封装与连接池实战指南

后端Web框架微服务RPC框架异步编程 【免费下载链接】hyperf 🚀 A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease. 项目地址: https://gitcode.com/hyperf/hyperf 点击查看 免费下载 …

2026/10/12 0:30:14 阅读更多 →
指针仪表检测数据集实战:1000张图与三种标签格式的YOLO训练指南

指针仪表检测数据集实战:1000张图与三种标签格式的YOLO训练指南

简介:这份YOLO指针仪表目标检测数据集面向计算机、电子信息工程、数学等专业的学生与算法初学者,可用于课程设计、期末大作业和毕业设计中的目标检测训练与验证任务。压缩包共2000个文件,约20.25MB,包含1000张指针仪表图片&#x…

2026/10/12 0:30:14 阅读更多 →
基于深度学习的智慧教室:专注度分析与作弊检测实战

基于深度学习的智慧教室:专注度分析与作弊检测实战

简介:这份资源是面向计算机相关专业学生与项目实战学习者的智慧教室系统源码,核心围绕基于深度学习的课堂专注度分析与考试作弊检测两大功能展开,可作为毕业设计、课程设计或期末大作业的完整参考方案。压缩包共626个文件,约87.73…

2026/10/12 0:29:13 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →