【Java 多线程处理 PDF 转PNG】基于 Spring @Async + CompletableFuture

Java OCR技术实战:Tess4J实现图片转文字 OCR(光学字符识别)技术通过算法将图像中的文字转换为可编辑文本,其核心在于模式识别和机器学习。Java生态中通过Tess4J封装Tesseract引擎实现OCR功能,结合JNI技术调用本地库,适合构建高稳定性的企业级应用。在文档数字化、票据识别等场景中,通过图像预处理、多线程优化等手段可显著提升识别准确率。本文以Tess4J为例,详解从环境配置到Docker化部署的全流程实践,特别针对中文识别和性能优化提供解决方案。 阅读详情

1️⃣ 背景

假设我们有一个 PDF 文件,需要:

  1. 将每页渲染成图片

  2. 编码为 PNG

  3. 上传到服务器

  4. 获取访问 URL

如果 PDF 很大,顺序处理每页很慢。
解决办法:多线程并行处理每页。


2️⃣ 核心技术点

  1. @Async

    • Spring 提供的异步执行注解

    • 方法加上 @Async 后,会被线程池异步调用

    • 必须在 Spring 管理的 Bean 中调用

  2. 线程池(ThreadPoolTaskExecutor)

    • 控制并发数量,防止内存/CPU 过载

    • 示例:

    @Bean("doSomethingExecutor")
    public Executor doSomethingExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(4);
        executor.setMaxPoolSize(8);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("pdf-async-");
        executor.initialize();
        return executor;
    }
    

  3. CompletableFuture

    • 用于收集异步任务的返回结果

    • 可以统一等待所有任务完成或处理异常


3️⃣ 核心步骤

步骤1:定义异步方法

@Async("doSomethingExecutor")
public CompletableFuture<String> processPage(String filePath, int pageIndex) {
    try (PDDocument document = PDDocument.load(new File(filePath))) {
        PDFRenderer renderer = new PDFRenderer(document);
        BufferedImage image = renderer.renderImageWithDPI(pageIndex, 96, ImageType.RGB);

        // 转 PNG
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "PNG", baos);
        image.flush();

        // 上传
        String objectName = UUID.randomUUID() + ".png";
        try (InputStream inputStream = new ByteArrayInputStream(baos.toByteArray())) {
            fileClient.putObject("application-file", objectName, inputStream);
        }

        String fileUrl = fileClient.getObjectIPUrl("application-file", objectName);
        return CompletableFuture.completedFuture(fileUrl);
    } catch (Exception e) {
        CompletableFuture<String> failedFuture = new CompletableFuture<>();
        failedFuture.completeExceptionally(e);
        return failedFuture;
    }
}

重点:

  • 每页任务独立,避免 PDDocument 多线程安全问题

  • 异常通过 completeExceptionally 返回


步骤2:触发异步任务(for 循环)

List<CompletableFuture<String>> futures = new ArrayList<>();

for (int i = 0; i < pageCount; i++) {
    futures.add(pdfPageProcessor.processPage(filePath, i));
}

// 等待所有任务完成
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

// 获取结果
List<String> urls = futures.stream()
        .map(CompletableFuture::join)
        .collect(Collectors.toList());

解释:

  • 循环只是触发任务,真正并行是线程池执行

  • allOf.join() 等待所有任务完成

  • join() 可以获取每页的 URL 或抛出异常


步骤3:控制并发

  • PDF 渲染是内存密集型操作

  • 建议线程池核心数 4~8,根据服务器配置调整

executor.setCorePoolSize(4); executor.setMaxPoolSize(8);

  • 避免一次性开太多线程导致 OOM


4️⃣ 流程示意

主线程
 │
 │  for i = 0..N-1
 │
 ├─> 调用 @Async 方法
 │       │
 │       └─> 提交任务到线程池
 │               │
 │               ├─> 线程1 执行第1页
 │               ├─> 线程2 执行第2页
 │               └─> ...
 │
 └─> CompletableFuture.allOf 等待完成
         │
         └─> 收集每页 URL

5️⃣ 优化建议

  1. 一次性加载 PDF

    • 避免每页都重新打开 PDF 文件

    • 每页可创建独立 PDFRenderer 渲染

  2. 降低 DPI 或控制图片大小

    • 减少内存占用

  3. 合理控制线程池大小

    • 避免 CPU 或内存过载

  4. 异常统一处理

    • 避免部分页失败被吞掉


6️⃣ 总结

  • 多线程的关键:@Async + 线程池

  • 循环只是触发异步任务,不是真正的并行

  • CompletableFuture 用于收集结果

  • 内存/线程池大小是性能瓶颈

Java实现Excel高保真转PDF:Aspose.Cells工具类实战与避坑指南 在数据处理与报表交付领域,文件格式转换是常见的工程需求,其核心在于确保信息在跨平台、跨媒介传递时的完整性与一致性。从技术原理上讲,这涉及到文档结构解析、样式渲染引擎和输出标准化三个关键环节。对于Java开发者而言,实现高保真转换的技术价值在于打通数据生产与标准化交付流程,保障财务、审计等场景下报表内容的精准无误。应用场景广泛覆盖了需要将包含复杂公式、图表及特定排版的Excel文件,无损转换为便于分发、打印和归档的PDF文档的各类业务系统。本文聚焦于利用Aspose.Cells这一专业商业库,通过深度配置其P 阅读详情

相关推荐

Spring Boot Base64文件上传:从解码到生产级安全存储全解析

Base64编码是一种将二进制数据转换为ASCII字符串的编码方案,常用于在文本协议(如JSON、XML)中安全传输文件数据。其原理是将每3个字节的二进制数据编码为4个可打印字符,便于网络传输且避免数据损坏。在Web开发中,这种技术价值在于能够无缝集成文件上传功能到基于JSON的RESTful API中,尤其适用于图片处理、Canvas绘图输出等前端直接生成Base64数据的场景。然而,直接将Base64字符串解码存储为文件,会面临内存溢出、恶意文件上传、存储扩展性等工程挑战。本文以Spring Boot框

weixin_34377919的博客 500

Java使用多线程完成PDF文件转图片

多线程完成PDF文件转图片 系统需要将PDF文件由后台直接转为img图片,供前端页面直接展示,不需要用户下载即可预览文件内容。直接转换时如果文件过大,耗时很长,影响用户体验,后调研后使用多线程方式进行,显著加快图片转换速度。 1、创建线程池 ExecutorService executorService = new ThreadPoolExecutor(5, 10, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(50));

wmf_helloWorld的博客 2747

Java集成钉钉审批:附件上传与流程创建实战指南

企业应用集成是现代企业提升运营效率的关键技术,其核心原理在于打通异构系统间的数据与流程壁垒。通过API接口调用与数据格式转换,实现业务自动化流转,其技术价值在于消除信息孤岛、减少人工干预并保障数据一致性。在办公自动化(OA)与业务流程管理场景中,与钉钉、企业微信等平台集成是常见需求。本文聚焦于钉钉审批流这一高频应用场景,深入探讨如何通过Java技术栈,特别是Apache HttpClient与Jackson库,稳定高效地实现**附件上传**与**审批实例创建**。文章将详细解析从获取AccessToken、

weixin_34008784的博客 1249

java图片处理以及pdf转图片

java图片处理以及pdf转图片1.需求之前项目里面有用到显示pdf的模块,需要将pdf显示处理,也结合了一些插件,pdf.js是firefox浏览器推出的一套h5渲染pdf的前端插件,支持移动端pc端,但是显示效果不太好,有时候需要嵌套到移动的webview里面,显示时候会有问题,pc端,由于直接采用iframe就支持,但是个别浏览器还是不支持,所以为了一次性解决兼容,把所有的pdf转换成图片就行

都市桃源 6325

Java实现Office文档在线预览:从POI到生产级架构全解析

文档在线预览是OA、知识库等企业级应用的核心功能,其技术原理主要基于文档格式转换,将Word、Excel、PPT等二进制文件转换为前端可直接渲染的HTML或图片格式。这项技术的工程价值在于提升用户体验与数据安全性,避免了依赖本地软件或第三方服务的局限。在Java技术栈中,Apache POI作为基础库,结合XDocReport、PDFBox等工具,构成了实现文档转换的主流方案。实际应用时,需综合考量字体兼容性、内存管理、异步处理等生产级问题,例如通过LibreOffice命令行工具增强格式支持,并利用缓存与

weixin_34236869的博客 372

Spring Controller原理与最佳实践:从MVC设计到Spring Boot 3.x落地

Spring Controller是Spring MVC架构中承接HTTP请求的核心组件,其本质是MVC模式在Java Web中的工程化实现,通过DispatcherServlet、HandlerMapping与HandlerAdapter协同完成请求路由、参数绑定与响应渲染。它并非简单注解标记,而是承担协议适配、数据契约定义与入口守门职责的关键层。理解@Controller与@RestController的语义差异、@RequestParam/@PathVariable/@RequestBody的协议层级

weixin_33901926的博客 133

Spring Boot异步文件上传FileNotFoundException根源分析与解决方案

在Java Web开发中,文件上传是常见的功能需求,其核心原理涉及HTTP协议、Servlet容器对multipart/form-data请求的解析,以及服务器端对文件流的处理。Spring MVC框架通过MultipartFile接口封装了上传文件,简化了开发,但在高并发或异步场景下,其底层依赖的临时文件机制可能引发资源生命周期管理问题,导致文件处理失败。这直接影响了Web应用的可靠性和用户体验。具体到Spring Boot项目,当使用@Async注解进行异步文件处理时,由于Servlet容器的临时文件清

cuiji1279的博客 318

Java浏览器自动化实战:Jvppeteer核心原理与工程应用指南

浏览器自动化是现代软件开发中的关键技术,它通过程序控制浏览器行为,模拟用户交互,广泛应用于自动化测试、数据采集和网页监控等场景。其核心原理基于浏览器开发者工具协议(如Chrome DevTools Protocol),允许外部程序与浏览器内核通信,执行导航、操作DOM、拦截网络请求等底层操作。这一技术为开发者提供了高效、可重复的网页操作能力,显著提升了测试覆盖率和数据获取效率。在Java技术栈中,Jvppeteer作为Puppeteer的Java实现,通过JNA技术封装,让开发者能在熟悉的JVM生态中直接驱

weixin_34124651的博客 427

Spring Boot文件上传实战:从Ruoyi-AI报错到安全部署全解析

文件上传是Web应用开发中的基础功能,其原理涉及HTTP协议、表单数据处理和服务器端文件I/O操作。在Spring Boot框架中,通过MultipartFile对象和自动配置机制,开发者可以便捷地处理文件上传请求。这项技术的核心价值在于为各类应用提供稳定的媒体资源输入能力,广泛应用于知识库系统、内容管理平台和用户头像上传等场景。然而,在实际工程实践中,开发者常会遇到文件扩展名校验失败、大小限制不生效以及存储路径权限等典型问题。本文以Ruoyi-AI项目中出现的“File Extention not sup

aizexi2652的博客 458

Spring Boot文件上传疑难排查:从Nginx代理到后端配置的完整解决方案

文件上传是Web应用开发中的基础功能,其原理基于HTTP协议的multipart/form-data编码格式,允许客户端在单个请求中发送二进制数据和表单字段。在技术实现上,Spring Boot通过Servlet容器的Multipart解析器处理上传请求,而Nginx等反向代理则负责请求的转发与负载均衡。这一机制的技术价值在于提供了统一、高效的数据传输方式,是用户提交图片、文档等非文本内容的核心入口。然而,在生产环境的复杂应用场景中,尤其是像Ruoyi-AI这类整合了AI能力的项目,文件上传常因配置不当引发

weixin_30383279的博客 109

Qoder:本地化Agentic编程环境与AI协同开发范式

Agentic编程是一种以目标分解、工具调用和反思验证为核心的智能开发范式,区别于传统补全式AI编码工具;其核心原理在于将自然语言需求转化为可执行的AST操作序列,并在本地完成模型推理与代码生成,确保数据安全与行为确定性;技术价值体现在工程规范强制落地、全链路可审计、离线高可靠等企业级能力;典型应用场景包括无网环境开发、金融/政务等强合规系统重构、混合技术栈集成及RAG+LangGraph类AI应用编排;Qoder正是这一范式的代表性落地实现,深度融合Qwen-Coding领域模型与本地RAG Kernel

weixin_34195364的博客 328

Python与Java 2020技术选型实战指南:快速原型vs企业级稳定

编程语言选型本质是工程约束下的决策平衡:Python作为解释型动态语言,依托CPython解释器与丰富数据科学生态(如pandas、scikit-learn),将‘人类理解成本’和‘假设验证速度’降至最低,天然适配MVP开发、自动化运维与AI模型迭代;Java则凭借JVM虚拟机、强类型系统与成熟企业级生态(Spring Boot、GraalVM),在高并发、长生命周期、强一致性场景中提供可验证的运行时确定性。二者并非替代关系,而是面向不同SLA需求的技术分工——当任务瓶颈在于业务逻辑表达效率,Python是

weixin_30687051的博客 362

智能车视觉算法实战:十字路口与弯道拐点的精准识别

本文深入探讨了智能车视觉导航中十字路口与弯道拐点的精准识别算法。通过实战经验,详细解析了如何利用纵向巡线法生成边界数组,并从中高效提取“上拐点”与“下拐点”的关键特征。文章重点分享了提升算法鲁棒性的核心技巧,包括图像预处理、ROI设置、状态机应用及多特征融合,旨在帮助开发者实现智能车在复杂路况下从“看见”到“看懂”的稳定决策。

weixin_29061465的博客 633

GLM-5-Code-Engine:面向工程落地的开源代码推理栈

大模型写代码已从语法补全迈向工程级生成——其核心在于对编程语言结构(AST)、项目上下文(Git/Confluence/Jira)和团队规范(安全策略/编码约定)的深度建模。GLM-5-Code-Engine并非单纯开源权重,而是融合符号缓存(symbol-cache)、多源上下文图谱(MSCI)与三层校验(SGOV)的可部署推理框架,显著提升首次生成通过率与生产就绪度。它适用于中高级工程师在Spring Boot、微服务重构、遗留系统适配等真实场景中的高信噪比代码生成与决策辅助,标志着AI编程正从‘工具增

cqwmy840702的博客 571

视觉定位避坑指南:基于双mark点的坐标转换常见错误排查

本文详细解析了工业视觉项目中基于双mark点的坐标转换常见错误及排查方法,涵盖旋转矩阵构建、坐标系原点选择、图像预处理优化等关键环节。通过实战案例和代码示例,帮助工程师避免定位偏差,提升系统精度,特别适用于自动化检测和精密制造场景。

7z8x2c4v6b9的博客 167

基于CODESYS与EtherCAT的步进电机单轴控制实践

本文详细介绍了基于CODESYS平台与EtherCAT总线技术实现步进电机单轴控制的完整实践流程。从硬件选型、软件工程创建、EtherCAT主从站配置,到运动控制功能块编程与在线调试,手把手指导读者完成从零到一的搭建,并提供了常见问题的排坑指南,帮助自动化开发者快速掌握这一高效、灵活且成本可控的工业运动控制解决方案。

hh234的博客 491

LlamaIndex Workflow 7大模式实战:分支/循环/并发/嵌套/流式/子类化/可视化,每个模式踩了1个坑

事件命名规范XXXEvent,见名知意状态隔离:多用户使用,避免全局状态污染异常处理:步骤内try/except,统一错误事件超时控制防止步骤卡死流式优先:用户交互使用测试:单元测试每个步骤,模拟事件输入日志:开启工作流日志,排查问题。

专注 Java / Python 开发,AI 大模型应用学习,持续输出源码教程,实战项目案例,学习笔记,拒绝空话,只写能直接跑的代码与可落地方案,关注我,一起少走弯路。 591

Obsidian和Typora图片路径同步终极指南:告别混乱的assets文件夹

本文详细解析了Obsidian与Typora图片路径同步的终极解决方案,通过Custom Attachment Location插件实现动态路径管理,解决了两款工具间图片兼容性问题。文章提供了从基础配置到高级应用的完整指南,帮助用户告别混乱的assets文件夹,提升工作效率。

g9h0i1的博客 821

InnoDB 内存结构总览:Change Buffer、AHI 与 Log Buffer

本文系统梳理InnoDB内存结构中的ChangeBuffer、Adaptive Hash Index(AHI)与LogBuffer。ChangeBuffer缓存二级索引页不在内存时的变更,减少随机IO,仅在页加载时合并;聚簇索引修改立即执行,因数据本身不可延后。AHI基于高频等值查询自动构建哈希索引,加速定位,仅支持等值操作。LogBuffer为redo log内存缓冲,配合磁盘日志实现崩溃恢复。三者均服务于性能优化,其中ChangeBuffer与AHI共享BufferPool空间,而LogBuffer独立

bksczm的博客 278

高频面波成像实战:从频散曲线到全波形反演

面波勘探是近地表工程勘察的重要手段,其核心原理在于不同频率的面波对地下介质的敏感深度不同,由此形成的频散曲线能够反映浅层剪切波速结构。相较于传统钻探与折射波法,高频面波成像具有无损、高效、对低速夹层敏感等优势,广泛应用于路基检测、空洞探测、滑坡调查等领域。在实际工程中,从野外采集的排列设计、震源选型,到频散谱提取与频散曲线反演,每一步都直接影响成像精度。然而频散反演受限于一维层状假设,难以刻画横向剧烈变化的地质体。全波形反演通过拟合完整波形信息,能够突破频散曲线的分辨率边界,获得更精细的近地表速度模型。本文

weixin_29090917的博客 270

YOLOv11改进 | 注意力篇 | YOLOv11引入24年最新的ELA注意力机制,并构建C2PSA_ELA

为了解决这些限制,本文介绍了一种高效的本地注意力(ELA)方法,实现了一个简单的结构,大幅度的性能改善。我们精心设计了ELA中的三个超参数,产生了四个不同的版本:ELA-T,ELAB,ELA-S和ELA-L,以满足不同视觉任务的具体要求,如图像分类,目标检测和语义分割。到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv11改进有效涨点专栏,本专栏目前为新开的,后期我会根据各种前沿顶会进行论文复现,也会对一些老的改进机制进行补充,如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~

tsg6698的博客 1284

Spring AI + GPT-5.5 + Ollama 配置教程:Base URL、超时与流式调用

由于不同 Spring AI、Spring Boot 小版本之间仍可能存在差异,创建项目时应检查 Spring Initializr、Spring AI BOM 和官方兼容矩阵,不要直接复制旧教程中的 Starter 名称和版本号。多人项目最好隔离不同客户端,并在脱敏前提下记录最终 URL、状态码、请求耗时、请求 ID 和模型 ID。Spring AI 接入模型 API,至少要同时确认 Starter、Base URL、请求路径、API Key、模型 ID、连接超时、读取超时和流式客户端这 8 项。

2601_95893075的博客 232

【机器人学】常用的小车底盘运动学模型推导(附C++代码)

认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!本文先对小车底盘运动学模型介绍做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章提示:以下是本篇文章正文内容对于小车的分析,仅仅考虑XY轴的线速度和Z轴的角速度,不考虑和横滚和俯仰的速度,【防盗标记–盒子君hzj】也不考虑Z轴的高度变化【即:车底盘的运动可以用三个独立变量来描述:x轴平动、y轴平动、yaw轴转动】

qq_35635374的博客 1931

V8 机制、手写核心函数与 TypeScript 类型体操

或固定初始化(如数组先定长、对象先给全字段)保持类型与形状稳定;这些都比"换框架"更基础。只能处理纯数据(丢函数、Date、RegExp、循环引用报错)。生产级深拷贝要处理:原始值短路、循环引用、V8(Chrome / Node 的 JS 引擎)不是"解释一行跑一行"那么简单,它用。图:V8 执行流程——解释执行 + 热点优化,优化失败会 Deopt 回退。JS 内存自动管理,但"自动"不等于"不会漏"。是"固定间隔最多执行一次"。手写 Promise 是"懂异步"的试金石。是"停下后才执行最后一次",

qq_38468358的博客 346

【PINN物理信息网络】基于PINN物理信息网络求解圆柱坐标中的热方程(python)

【PINN物理信息网络】基于PINN物理信息网络求解圆柱坐标中的热方程(python)

k8291121的博客 2273

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

要努力去发光,而不是被照亮~ 125

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

上一篇: 【RabbitMQ实现延迟任务+重试机制】Springboot+RabbitMQ+多线程消费。1.失败会重试三次2.超过最大重试次数就写表+@Scheduled查询、执行业务、删数据,3.发异常短信
下一篇: 【生产环境MinIO版本升级+主备方案脚本】
alan0721
博客等级 码龄10年 29粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值