【Java】基于Pdfbox解析PDF文档中指定位置的文字和图片

1.1 PDFBOX介绍

Apache PDFBox是一个开源Java库,支持PDF文档的开发和转换。 我们可以使用PDFBox开发可以创建,转换和操作PDF文档的Java程序。PDFBox的主要功能:

  • Extract Text - 使用PDFBox,您可以从PDF文件中提取Unicode文本。
  • Split & Merge - 使用PDFBox,您可以将单个PDF文件分成多个文件,并将它们合并为一个文件。
  • Fill Forms - 使用PDFBox,您可以在文档中填写表单数据。
  • Print - 使用PDFBox,您可以使用标准Java打印API打印PDF文件。
  • Save as Image - 使用PDFBox,您可以将PDF保存为图像文件,如PNG或JPEG。
  • Create PDFs - 使用PDFBox,您可以通过创建Java程序创建新的PDF文件,还可以包含图像和字体。
  • Signing - 使用PDFBox,您可以将数字签名添加到PDF文件。

PDFBox的四个主要组成部分:

  • PDFBox - 这是PDFBox的主要部分。 它包含与内容提取和操作相关的类和接口。
  • FontBox - 它包含与font相关的类和接口,使用这些类我们可以修改PDF文档的文本字体。
  • XmpBox - 包含处理XMP元数据的类和接口。
  • Preflight - 此组件用于根据PDF/A-1b标准验证PDF文件。

PDFBOX操作PDF文档基本实现:

  • 创建PDF文档( Creating a PDF Document)
  • 添加页面( Adding Pages)
  • 删除页面( Removing Pages)
  • 读写文档属性( Document Properties)
  • 添加文本( Adding Text)
  • 添加多行( Adding Multiple Lines)
  • 读取文本( Reading Text)
  • 插入图像( Inserting Image)
  • 加密PDF文档(Encrypting a PDF Document)
  • 拆分PDF文档( Splitting a PDF Document)
  • 合并多个PDF文档(Merging Multiple PDF Documents)
  • 从PDF文档生成图像(Save Images)
  • 添加矩形( Adding Rectangles)

详细参考PDFBOX官网

1.2 项目需求分析

项目中需要根据既有的电子图书进行信息化的归档,方便分类目查询。因为图书主要是以如下排版存在:
在这里插入图片描述

相对来说页面分为左右两部分,右侧是知识点的描述,比较规范。左侧是图文的说明,为了生动,各种形式,大小都有,基本上没有规律,所以无法进行解析。最终敲定方案如下:

右侧描述根据章节来生成知识点描述,可以按章节或者关键字检索。对应描述的左侧部分,需要整体生成辅助说明一个图片。辅助说明相应的知识点内容。

拆分成技术实现为:

  • 指定区域进行PDF文字内容提取
  • 指定区域进行PDF图片内容提取

1.3 代码实现

1.3.1 SpringBoot工程引入PDFBox依赖

POM.xml

    <!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox -->
	<dependency>
	    <groupId>org.apache.pdfbox</groupId>
	    <artifactId>pdfbox</artifactId>
	    <version>2.0.18</version>
	</dependency>

PdfboxUtils.java

package com.gavinbj.common.utils;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.text.PDFTextStripperByArea;

public class PdfboxUtils {

	public static final String REGION_NAME = "content";

	
	/**
	 * 根据指定文件页码的指定区域读取文字
	 * 
	 * @param filePath PDF文件路径
	 * @param iPage PDF页码
	 * @param textRrect 读取文字的区域
	 * @return 文字内容
	 */
	public static String readRectangelText(String filePath, int iPage, Rectangle textRrect) {

		String textContent = "";
		
		try(PDDocument pdfDoc = PDDocument.load(new File(filePath))) {
			// 获取指定的PDF页
			PDPage pdfPage = pdfDoc.getPage(iPage);

			// 获取指定位置的文字(文字剥离器)
			PDFTextStripperByArea textStripper = new PDFTextStripperByArea();
			textStripper.setSortByPosition(true);
			textStripper.addRegion(REGION_NAME, textRrect);
			textStripper.extractRegions(pdfPage);

			textContent = textStripper.getTextForRegion(REGION_NAME);

			// 释放资源
			pdfDoc.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		} 

		return textContent;

	}
	
	/**
	 * 根据指定文件页码的指定区域读取图片
	 * 
	 * @param filePath PDF文件路径
	 * @param iPage PDF页码
	 * @param imgRrect 读取图片的区域
	 * @return 图片内容
	 */
	public static BufferedImage readRectangelImage(String filePath, int iPage, Rectangle imgRrect) {

		BufferedImage bufImage = null;
		try(PDDocument pdfDoc = PDDocument.load(new File(filePath))) {
			// 获取渲染器,主要用来后面获取BufferedImage
			PDFRenderer pdfRenderer = new PDFRenderer(pdfDoc);
			// 截取指定位置生产图片
			bufImage = pdfRenderer.renderImage(iPage).getSubimage(imgRrect.x,imgRrect.y,imgRrect.width,imgRrect.height); 

            // 释放资源
			pdfDoc.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		} 

		return bufImage;
	}
	
}

PdfTest.java:测试类

package com.gavinbj.common.utils;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class PdfTest {
	
	public static void main(String[] args) throws IOException {
		
	    String pdfPath="C:\\PDFDemos\\pdf\\9.pdf";
	    
	    Rectangle textRrect = new Rectangle(420, 80, 130, 245);
	    
	    String strContent = PdfboxUtils.readRectangelText(pdfPath, 0, textRrect);
	    
		System.out.println(strContent);
		
		// 保存图片
		Rectangle imgRrect = new Rectangle(0, 76, 420, 240);
		BufferedImage bufImage = PdfboxUtils.readRectangelImage(pdfPath, 0, imgRrect);
		
		File outputfile = new File("D:\\pdfImage2.png");
        ImageIO.write(bufImage, "png", outputfile);
		
	}
	
}

执行测试结果:

一、太阳辐射
1 …概念:太阳源源不断地
以电磁波的形式向四周放射能
量,被称为太阳辐射。
太阳辐射携带巨大的能量。
地球所接收到的太阳辐射能量仅
为太阳向宇宙空间放射的总辐射
能量的二十亿分之一。
在日地平均距离处与太
阳光垂直的地球大气上界单位
面积上在单位时间内所接收到
的太阳辐射的所有波长的总能
量,称为太阳常数。

在这里插入图片描述

结论:从上面例子可以看出使用PDFBOX相应的方法可以读取指定位置的文字。

并可以从指定位置提取图片并保存,不同于直接读取PDF中内嵌的对象,可以根据你的指定区域直接截取相应的内容作为图片保存,但是处理速度不敢恭维,特别慢。暂时没有想到优化的办法。

  • 14
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
基于Java和Python的爬虫项目实战源码.zip 自己动手写网络爬虫》,并基于Python3和Java实现 为什么采用宽度优先搜索策略? 深度优先遍历可能会在深度上过“深”而陷入“黑洞”; 重要的网页往往距离种子网页比较近,越深的网页的重要性越低; 万维网深度最多17层,但到达某面总存在一条很短的路径,宽度优先遍历会以最快的速度达到这个网页; 宽度优先遍历有利于多爬虫的合作抓,多爬虫合作通常先抓站内链接,抓的封闭性很强; 解析HTML网页---Jsoup Maven配置: <dependency> <groupId>org.jsoup</gorup> <artifactId>jsoup</artifactId> <version>1.10.3</version> </dependency> 正则表达式: 对URL进过滤,只提符合特定格式的链接; 提网页内容; HTMLParser: 文本抽; 链接抽; 资源抽; 链接检查; 站点检查; URL重写; 广告清除; 将HTML页面转化成XML页面; HTML页面清理; Rhino是一个由Java实现的JavaScript语言解析引擎,Rhino的主要功能是管理脚本执时的运环境 非HTML解析PDF文件:PDFBox解析PDF文件 FontBox:处理PDF字体的Java类库 JempBox处理XMP元数据 的Java类库 Office文档:POI项目 POI读写Excel、Word、PPT文件 POI-HSMF读写Outlook POI-HDGF读写Visio POI-HPBF支持Publisher 其他文件 多媒体内容: 抽视频内容 视频内容一般分为四部分:帧、镜头、情节和节目 关键帧的提---动态规则策略、基于视觉模型的自适应关键帧提策略、基于镜头边界系数的关键帧提策略 基于镜头边界系数的关键帧提分3个步骤进: 设置最大关键帧数M 每个镜头的非边界过渡区的第一帧确定为关键帧 【找镜头边界:基于帧差的镜头边界检测方法、基于模型的镜头边界检测方法、基于学习的镜头边界检测方法】 使用非极大值抑制法确定镜头边界系数极大值并排序,以实现基于镜头边界系数的关键帧提 JMF(Java视频处理): 功能 a)在Java Applet和应用程序播放贵重物品媒体文件,如AVI、MPEG、WAV等; b)可以播放从互联网上下载的媒体流; c)可以利用麦克风、摄像机等设备截音频和视频,并只在成多媒体文件; d)处理多媒体文件,转换成文件格式; e)向互联网上传音频和视频数据流; f)在互联网上播放音频和视频数据; 组件 a)数据源,如一个媒体文件 b)截设备,如麦克风、摄像机等 c)播放器-Player,JMF的接口是Player,将音频/视频数据流作为输入,将数据流输出到音箱或屏幕上 d)处理器-Processor,Processor接口继承了Player接口,支持Player对象所支持的功能外还可以控制对于输入的多媒体数据流进何种处理以及通过数据源向其他Player对象或Processor对象输出数据 e)数据格式-Format,保存多媒体格式信息 f)管理器,4种管理器Manager、PackageManager、CaptureDeviceManager、PlugInManager Sourceforge-org.farng.mp3(Java音频处理): 音乐:歌手名+歌曲名等元信息,以MP3文件大体分为三部分: a) TAG_V2(ID3V2) 包含了作者、作曲、专辑等信息,长度不固定,扩充ID3V1信息 b) Frame 一系列的帧,由帧头(MP3的位率、采样率、版本等信息)和数据实体两部分组成 c) TAG_V1(ID3V1) 包含作者、作曲、专辑等信息,长度128字节 解析Json数据---Json Maven配置: <dependency> <groupId>com.alibabap</gorup> <artifactId>fastjson</artifactId> <version>1.2.35.3</version> </dependency> 评估页面的重要程度 链接的欢迎程度---反向链接(即指向当前URL的链接)的数量和质量决定的,定义为IB(P); 链接的重要程度---关于URL字符串的函数,仅仅考察字符串本身,比如认为".com"和"home"的URL比".cc"和"map"高,定义为IL(P); 平均链接的深度---根据上面所分析的宽度优先的原则,计算全站的平均链接深度,然后认为距离种子站点越近的重要性越高
Java可以使用开源库Apache PDFBox解析PDF文件,包括提文本和图片。以下是一个简单的示例代码,演示如何读取PDF的文本和图片: ```java import java.io.File; import java.io.IOException; import java.util.List; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.text.PDFTextStripper; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.pdfbox.rendering.ImageType; import org.apache.pdfbox.rendering.RenderedImage; public class PDFParser { public static void main(String[] args) throws IOException { // 读取PDF文件 PDDocument document = PDDocument.load(new File("example.pdf")); // 提文本 PDFTextStripper stripper = new PDFTextStripper(); String text = stripper.getText(document); System.out.println("文本内容:\n" + text); // 提图片 List<PDPage> pages = document.getPages(); PDFRenderer renderer = new PDFRenderer(document); int pageNum = 1; for (PDPage page : pages) { // 渲染页面为图像 RenderedImage image = renderer.renderImageWithDPI(pageNum - 1, 300, ImageType.RGB); // 保存图像到文件 File outputFile = new File("page" + pageNum + ".png"); ImageIO.write(image, "png", outputFile); pageNum++; } // 关闭文档 document.close(); } } ``` 此示例将提PDF文件的文本并将其打印到控制台,然后提每个页面的图像并将其保存到文件。请注意,这将生成一个PNG图像文件,其包含PDF页面的可见内容。如果您需要提PDF的矢量图形,请使用不同的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值