图片与PDF文件相互转换

图片与PDF文件相互转换

  • 一、概述
  • 二、提取PDF文件中的图片
    • 2.1代码实现
    • 2.2注意要点
      • 2.2.1代码使用
      • 2.2.2依赖包
      • 2.2.3图片序号设置
  • 三、图片转换为PDF文件
    • 3.1代码实现
    • 3.2注意要点
      • 3.2.1代码使用
      • 3.2.2PDF文件尺寸设置
      • 3.2.3PDF文件中图片尺寸计算

一、概述

本文实现了提取PDF文件中包含的图片,和将多个图片合并转换为PDF文件,并给出了相应的python代码,说明了其中的几处注意要点。

二、提取PDF文件中的图片

2.1代码实现

python代码如下:

import fitz
import io
from PIL import Image
import osdef extract_images_from_pdf(pdf_path, outputImg_folder):if not os.path.exists(outputImg_folder):os.makedirs(outputImg_folder)# 打开PDF文件pdf_document = fitz.open(pdf_path)# 遍历PDF中的每一页for page_number in range(len(pdf_document)):page = pdf_document.load_page(page_number)image_list = page.get_images(full=True)# 遍历每个页面中的每张图片for image_index, img in enumerate(image_list):xref = img[0]base_image = pdf_document.extract_image(xref)image_bytes = base_image["image"]# 将图像字节转换为PIL图像image = Image.open(io.BytesIO(image_bytes))# 生成输出文件名output_file = f"{outputImg_folder}/image_page_{page_number + 1:0=3d}_{image_index + 1:0=3d}.{image.format.lower()}"# 保存图像image.save(output_file)print(f"保存图像: {output_file}")

2.2注意要点

2.2.1代码使用

需要注意的是,上述代码只能提取非扫描的PDF文档,如果是扫描的PDF文档,那么会将文档每一页当作图片提取出来。

2.2.2依赖包

上述代码主要是使用fitz软件包实现的PDF文件中图片提取,fitz也叫PyMuPDF,安装命令如下:

pip install pymupdf

2.2.3图片序号设置

代码在给提取的图片命名时,将图片序号设置为3位数字,不足3位则自动补零,保证了在后续处理中能够获得排序正确的图片列表。

三、图片转换为PDF文件

3.1代码实现

python代码如下:

def convert_images_to_pdf(img_path, output_pdf_path, adjust=True):# 创建PDF文件c = canvas.Canvas(output_pdf_path, pagesize=letter)width, height = letterpage_width = widthpage_height = heightrenderDPI = 96image_paths = []if os.path.isfile(img_path):image_paths.append(img_path)elif os.path.isdir(img_path):image_extensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tif', 'tiff']for filename in os.listdir(img_path):image_paths.append(os.path.join(img_path, filename))else:print('图片路径输入错误')returnfor image_path in image_paths:# 打开图片image = Image.open(image_path)image_width, image_height = image.sizeif adjust:# 调整图片尺寸以适应页面,居中显示,保持图片长宽比例aspect = image_width / image_heightif image_width > image_height:canvas_width = page_widthcanvas_height = page_width / aspectelse:canvas_height = page_heightcanvas_width = page_height * aspectif canvas_width > page_width:canvas_width = page_widthcanvas_height = page_width / aspectif canvas_height > page_height:canvas_height = page_heightcanvas_width = page_height * aspect# 计算图片的居中位置x = (page_width - canvas_width) / 2y = (page_height - canvas_height) / 2else:canvas_width = image_width / renderDPI * 72canvas_height = image_height / renderDPI * 72# 设置页面大小与图片尺寸匹配c.setPageSize((canvas_width, canvas_height))x = 0y = 0# 添加图片到PDF页面c.drawImage(image_path, x, y, canvas_width, canvas_height)c.showPage()  # 创建新的一页print(image_path)c.save()  # 保存PDF文件

3.2注意要点

3.2.1代码使用

上述代码根据传入参数自动判断图片数量为单张或多张,实现了单张或多张图片转换为PDF文件,每张图片占一页PDF。
转换后的PDF文件尺寸有两种选项,通过adjust参数控制,一种是统一设定PDF文件所有页面尺寸,为适应尺寸图片会被缩放,但保留长宽比,另一种是不对图片进行缩放,每一页文档的尺寸随图片的尺寸不同而变化

3.2.2PDF文件尺寸设置

当adjust为True时,PDF文件所有页面尺寸会被统一设置,代码中设置为letter信纸尺寸:8.5 x 11 英寸,此时图片将被缩放,只保留长宽比,缩放后的图片居中显示,此时不需要计算图片尺寸,只需计算图片的长宽比。

需要注意的是,图片虽然被缩放,但图片的质量并没有被改变。在PDF查看器的缩放比例为100%时,缩放后的图片可能会显得模糊,但只要调整缩放比例就能够清晰显示。

关于PDF文件尺寸更多详细信息,可参照本博客的另一篇文章:DPI简析。

3.2.3PDF文件中图片尺寸计算

当adjust为False时,不对图片进行缩放,每一页文档的尺寸随图片的尺寸不同而变化,那么此时需要计算出PDF文件中图片的尺寸大小。

尺寸属性并不是图片的固有属性,只有在打印或显示图片时,图片才具有尺寸属性,而PDF文件布局是以尺寸为量化标准的,PDF中尺寸的单位为点(points),1点等于1/72英寸,所以需要计算出图片在PDF中的尺寸。

PDF文件在显示时会首先被渲染,将尺寸转换为像素,像素数=尺寸×渲染DPI,根据这个公式可以反推出图片在PDF文件中的尺寸,即=图片像素数÷渲染DPI,此时单位为英寸,还应转换为点,所以完整的计算公式如下:
图片在PDF文件中的尺寸=图片像素数÷渲染DPI×72

此处的图片在PDF文件中的尺寸与图片的显示尺寸两个概念可能会让读者混淆,二者的关系其实是PDF的实际物理尺寸与显示尺寸的关系,更多信息可见DPI简析。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/36570.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

threadX netx 设置IP地址以及获取IP地址

ThreadX 是一个实时操作系统(RTOS)内核,而 NetX 则是 Express Logic 提供的一个嵌入式 TCP/IP 网络栈,它经常与 ThreadX 一起使用来提供网络功能。在 ThreadX 和 NetX 中设置和获取 IP 地址通常涉及几个步骤。 设置 IP 地址 初始…

怎么打印加密的Excel文件,有哪些方法?

很多小伙伴都喜欢使用Excel来创建或是编辑表格文档,因为Excel中的功能十分的丰富且强大,在Excel中我们可以对表格文档进行各种操作。有的小伙伴可能在打印时需要给每一页表格添加页码,但又不知道该在哪里找到相关操作,其实很简单&…

视频编解码从H.264到H.266:浅析GB28181安防视频汇聚EasyCVR视频压缩技术

随着信息技术的飞速发展,视频编解码技术也在不断革新,以适应高清、超高清甚至8K视频时代的到来。视频编解码技术作为数字多媒体领域的核心技术之一,也在不断地演进和革新。从早期的H.261到现在的H.265、H.266,每一次技术的升级都极…

electron线上更新

一、安装electron-updater npm install --save electron-updater二、在main.js中引入使用 import { autoUpdater } from electron; if (!isDev) {const serverUrl https://your-update-server.com; // 自定义更新服务器地址或GitHub Releases地址autoUpdater.setFeedURL(${…

GPT-5:编织未来智能的经纬

GPT-5技术突破预测 随着GPT-5的预告,人工智能的叙事正步入一个崭新的篇章。想象中的GPT-5不仅是自然语言处理(NLP)领域的革命,更是对“理解”本身的一次重新定义。它可能集成深度学习的最新进展,如自注意力机制的进一步…

Java将list数组中重复的对象进行去重

/*** 数组去重*/ public class ArrayDistinct {public static void main(String[] args) {ArrayList<Object> list new ArrayList<>();JSONObject jsonObject1 new JSONObject();jsonObject1.put("name","张三");jsonObject1.put("age&…

使用systemd管理Linux下的frps服务:安装、配置及自动化操作指南

在 Linux 系统下&#xff0c;使用 systemd 可以方便地控制 frps 服务端的启动、停止、配置后台运行以及开机自启动。以下是具体的操作步骤&#xff1a; 1. 安装 systemd 如果您的 Linux 服务器上尚未安装 systemd&#xff0c;可以使用包管理器如 yum&#xff08;适用于 Cent…

Python 斐波那契的几种实现方式

斐波那契数列是一个经典的数列&#xff0c;其中每个数字是前两个数字的和。数列开始于 0 和 1&#xff0c;即 0, 1, 1, 2, 3, 5, 8, 13, ...。在 Python 中&#xff0c;你可以使用多种方法来生成斐波那契数列。以下是几种常见的方法&#xff1a; 方法一&#xff1a;递归 递归…

Spring系统学习 - 基于注解管理Bean

什么是基于注解的方式管理Bean 在 Spring 框架中&#xff0c;基于注解的方式管理 Bean 是一种非常流行且现代的方法。它允许你通过在类、方法或字段上添加特定的注解来声明 Bean 的创建和依赖注入&#xff0c;从而避免了在 XML 配置文件中定义 Bean 的繁琐工作。 注解和 XML …

码农:如何快速融入团队

问题&#xff1a; 码农如何快速融入团队&#xff1f; 记住一个标准&#xff1a;能干事、能抗事。 总结一个字&#xff1a; 靠谱。 适用范围&#xff1a;新手码农、老司机码农、测试、DBA、运维、产品经理、项目经理、架构师、技术专家、。。。。适用于任何行业的打工者。 下面要…

电脑开机就一直在开机界面转圈,怎么回事?

前言 前段时间小白去给一位朋友修电脑。她说这个电脑很奇怪&#xff0c;有时候开机很快就进入电脑界面&#xff0c;但有时候开机一直在那转圈&#xff0c;半天也不见进入。 Windows7系统的小伙伴应该也有遇到过类似的问题&#xff0c;就是电脑一直在Windows的logo界面&#xf…

自动驾驶水泥搅拌车在梁场的应用(上)

北京渡众机器人科技有限公司的自动驾驶水泥搅拌车在梁场的应用可以极大地提升生产效率和安全性。通常情况下&#xff0c;梁场是用于预制混凝土梁的生产和装配的场地&#xff0c;传统上需要大量的人工操作和搅拌车的驾驶。引入自动驾驶技术可以带来以下几个显著的优势&#xff1…

AI进阶指南第五课,大模型相关概念(知识库,微调)

虽然前面大概讲了一下大模型的一些基本概念&#xff0c;但是那些都比较偏向于大模型本身&#xff0c;但是我们使用的时候如果只靠大模型肯定是不行的。 就好比如果一个人只有一个脑子&#xff0c;其他什么部位也没有的话&#xff0c;那场面。&#xff08;感觉现在网上的AI图片…

Java OA系统招聘管理模块

### 使用Spring Boot和MySQL构建一个完善的OA招聘管理系统 在企业的日常运作中&#xff0c;招聘管理系统是一个重要的组成部分。本文将介绍如何使用Spring Boot和MySQL构建一个完整的OA招聘管理模块。这个模块包含以下主要功能&#xff1a; 1. **岗位管理**&#xff1a;对岗位…

npm install报错Maximum call stack size exceeded

npm 报错 方案&#xff1a; npm cache clean --force npm install

成功解决​​​​​​​TypeError: __call__() got an unexpected keyword argument ‘first_int‘

成功解决TypeError: __call__() got an unexpected keyword argument first_int 目录 解决问题 解决思路 解决方法 T1、直接调用原始函数 T2、检查装饰器实现 T3、使用不同的调用方式 解决问题 result = multiply(**arguments) File "D:\ProgramData\Anaconda3\Li…

Redis 7.x 系列【10】数据类型之有序集合(ZSet)

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 常用命令2.1 ZADD2.2 ZCARD2.3 ZSCORE2.4 ZRANGE2.5 ZREVRANGE2.6 ZRANK2.7…

kettle使用手册 安装9.0版本 建议设置为英语

0.新建转换的常用组件 0. Generate rows 定义一个字符串 name value就是字符串的值 0.1 String operations 字段转大写 去空格 1. Json input 来源于一个json文件 1.json 或mq接收到的data内容是json字符串 2. Json output 定义Jsonbloc值为 data, 左侧Fieldname是数据库…

Grafana面试题精选和参考答案

目录 Grafana是什么以及它的主要应用场景 Grafana支持的数据源 Grafana的体系结构及主要组件 Grafana如何实现数据的可视化和监控 Grafana支持的图表类型 如何在Grafana中创建和编辑仪表盘 Grafana的查询编辑器功能 Grafana支持的认证方式 Grafana的性能调优建议 Gra…

常见的字符串函数(包含头文件string.h)和字符函数(2)

八. strstr函数 1.strstr的定义 char *strstr( const char *str1, const char *str2 ); ->1. strstr查找子串(str2)在字符串(str2)中第一次出现的位置&#xff0c;记录并返回该位置的指针&#xff0c;如果找不到&#xff0c;则返回NULL ->2. str1&#xff1a;查找字符…