前言:在最近的测试中遇到一个与PDF相关的测试需求,其中有一个过程是将PDF转换成图片,然后对图片进行测试。

粗略的试了好几种方式,其中语言尝试了Python和Java,总体而言所找到的Python方式相对比Java更快一些,更简单一些。

下面首先分享一下Python将PDF转换成图片,Java后续有时间在进行分享。

需求:我需要先将PDF转换成为PNG图片,并截取图片的一部分存储,然后作为测试目标进行测试。

操作:

1、PDF转PNG图片

2、对PNG图片进行指定区域截图,在另存到指定文件夹下

1、PyMuPDF将PDF转换成图片

import sys, fitzimport osimport datetimedef pyMuPDF_fitz(pdfPath, imagePath):startTime_pdf2img = datetime.datetime.now()#开始时间print("imagePath="+imagePath)pdfDoc = fitz.open(pdfPath)for pg in range(pdfDoc.pageCount):page = pdfDoc[pg]rotate = int(0)# 每个尺寸的缩放系数为1.3,这将为我们生成分辨率提高2.6的图像。# 此处若是不做设置,默认图片大小为:792X612, dpi=96zoom_x = 1.33333333 #(1.33333333-->1056x816) (2-->1584x1224)zoom_y = 1.33333333mat = fitz.Matrix(zoom_x, zoom_y).preRotate(rotate)pix = page.getPixmap(matrix=mat, alpha=False)if not os.path.exists(imagePath):#判断存放图片的文件夹是否存在os.makedirs(imagePath) # 若图片文件夹不存在就创建pix.writePNG(imagePath+'/'+'images_%s.png' % pg)#将图片写入指定的文件夹内endTime_pdf2img = datetime.datetime.now()#结束时间print('pdf2img时间=',(endTime_pdf2img - startTime_pdf2img).seconds)if __name__ == "__main__":pdfPath = '../path/demo.pdf'imagePath = '../path/image'pyMuPDF_fitz(pdfPath, imagePath)

PDF文档页数超过100页的话需要十几秒,因为先转换成一整张1056X816的图片,再对本地文件中的所有图片进行遍历截图,时间上比较慢,通过查看文档发现:

还可以在转换的同时指定图片的大小,对图片指定区域进行截取,这样快很多,一步到位,省去了二次截图的过程,前提是我们必须要知道想要截取哪一块区域并保存。

官方示例代码如下:

#下面的这段代码就是想要从一页PDF的中心点为起点截取到右下角的区域,截取整张图的1/4.>>> mat = fitz.Matrix(2, 2) # 在每个方向缩放因子2>>> rect = page.rect # 页面的矩形>>> mp = rect.tl + (rect.br - rect.tl) * 0.5 # 矩形的中心>>> clip = fitz.Rect(mp, rect.br) # 我们想要的剪切区域>>> pix = page.getPixmap(matrix = mat, clip = clip)

实际用到的例子是:

整张图片导出之后是1056*816,但是我想要的是这张图片最底部的部分1056*75,相当于PDF文档的页脚部分。

import sys, fitzimport osimport datetimedef pyMuPDF_fitz(pdfPath, imagePath):startTime_pdf2img = datetime.datetime.now()#开始时间pdfDoc = fitz.open(pdfPath)for pg in range(pdfDoc.pageCount):page = pdfDoc[pg]rotate = int(0)# 每个尺寸的缩放系数为1.3,这将为我们生成分辨率提高2.6的图像。# 此处若是不做设置,默认图片大小为:792X612, dpi=96zoom_x = 1.33333333 #(1.33333333-->1056x816) (2-->1584x1224)zoom_y = 1.33333333mat = fitz.Matrix(zoom_x, zoom_y).preRotate(rotate)pix = page.getPixmap(matrix=mat, alpha=False)if not os.path.exists(imagePath):#判断存放图片的文件夹是否存在os.makedirs(imagePath) # 若图片文件夹不存在就创建pix.writePNG(imagePath+'/'+'images_%s.png' % pg)#将图片写入指定的文件夹内endTime_pdf2img = datetime.datetime.now()#结束时间print('pdf2img时间=',(endTime_pdf2img - startTime_pdf2img).seconds)def pyMuPDF2_fitz(pdfPath, imagePath):pdfDoc = fitz.open(pdfPath) # open documentfor pg in range(pdfDoc.pageCount): # iterate through the pagespage = pdfDoc[pg]rotate = int(0)# 每个尺寸的缩放系数为1.3,这将为我们生成分辨率提高2.6的图像# 此处若是不做设置,默认图片大小为:792X612, dpi=96zoom_x = 1.33333333 #(1.33333333-->1056x816) (2-->1584x1224)zoom_y = 1.33333333mat = fitz.Matrix(zoom_x, zoom_y).preRotate(rotate) # 缩放系数1.3在每个维度 .preRotate(rotate)是执行一个旋转rect = page.rect # 页面大小mp = rect.tl + (rect.bl - (0,75/zoom_x)) # 矩形区域 56=75/1.3333clip = fitz.Rect(mp, rect.br) # 想要截取的区域pix = page.getPixmap(matrix=mat, alpha=False, clip=clip) # 将页面转换为图像if not os.path.exists(imagePath):os.makedirs(imagePath)pix.writePNG(imagePath+'/'+'psReport_%s.png' % pg)# store image as a PNGif __name__ == "__main__":pdfPath = '../path/demo.pdf'imagePath = '../path/image'#pyMuPDF_fitz(pdfPath, imagePath)#只是转换图片pyMuPDF2_fitz(pdfPath, imagePath)#指定想要的区域转换成图片

当然上面这种是综合下来最快的,另外PyMuPDF还可以对PDF进行追加删除之类的功能。

下面再介绍一种方法pdf2image

2、pdf2image将PDF转换成图片pdf2image也是个包装器,真正的转换工具是poppler

GitHub地址:https://github.com/Belval/pdf2image,上面也有相关的配置说明。

1、安装pdf2image: pip install pdf2image

2、Windows安装配置poppler(这里只介绍Windows,Mac和Linux去上面Github地址里面参考官网)

Windows用户必须为Windows安装poppler (http://blog.alivate.com.au/poppler-windows/),然后将bin/文件夹添加到PATH(开始>输入env>编辑系统环境变量>环境变量...>系统变量>Path)

注意:这里配置之后需要重启一下电脑才会生效,不然会报如下错误:

ERROE:FileNotFoundError: [WinError 2] The system cannot find the file specified

During handling of the above exception, another exception occurred:

3、pip install pillow (如果你还没有安装过的话)

from pdf2image import convert_from_path,convert_from_bytesimport tempfilefrom pdf2image.exceptions import (PDFInfoNotInstalledError,PDFPageCountError,PDFSyntaxError)def pdf2image2(pdfPath, imagePath, pageNum):#方法一:#convert_from_path('a.pdf', dpi=500, "output",fmt="JPEG",output_file="ok",thread_count=4)#这会将a.pdf转换成在output文件夹下形如ok_线程id-页码.jpg的一些文件。#若不指定thread_count则默认为1,并且在文件名中显示id. 这种转换是直接写入到磁盘上的,因此不会占用太多内存。#下面的写法直接写入到内存,images = convert_from_path(pdfPath, dpi=96)for image in images:if not os.path.exists(imagePath):os.makedirs(imagePath)image.save(imagePath+'/'+'psReport_%s.png' % images.index(image), 'PNG')#方法二:images = convert_from_bytes(open('/home/belval/example.pdf', 'rb').read())for image in images:if not os.path.exists(imagePath):os.makedirs(imagePath)image.save(imagePath+'/'+'psReport_%s.png' % images.index(image), 'PNG')#方法三,也是最推荐的方法with tempfile.TemporaryDirectory() as path:images_from_path = convert_from_path(pdfPath, output_folder=path, dpi=96)for image in images_from_path:if not os.path.exists(imagePath):os.makedirs(imagePath)image.save(imagePath+'/'+'psReport_%s.png' % images_from_path.index(image), 'PNG')print(images_from_path)

以下是参数定义:

pdf_path -->要转换的PDF文档路径

dpi -->DPI中的图像质量(默认为200),Windows默认为96dpi

output_folder -->将生成的图像写入文件夹(而不是直接写入内存)若是path不做指定的话,path的默认地址是:C:\Users\pzhang7\AppData\Local\Temp\生成的uuid4。

first_page -->从哪一页开始转换,默认是PDF的第一页

last_page -->转换到哪一页,默认是PDF的最后一页

fmt --> 输出图像格式默认格式是ppm,还可以设置为png和jpeg等

thread_count -->允许生成多少个线程进行处理,一般不超过4个线程;

userpw -->PDF的密码(若有密码的话需要添加)

use_cropbox --> 使用cropbox而不是mediabox

strict -->参数允许您使用自定义类型PDFSyntaxError捕获pdftoppm语法错误

transparent -->参数允许生成没有背景的图像,而不是通常的白色图像(为此需要pdftocairo)

single_file -->使用pdftoppm / pdftocairo中的-singlefile选项

output_file --> 输出文件名是什么

poppler_path -->查找poppler二进制文件的路径,允许用户使用poppler_path指定poppler的安装路径;默认不指定的话需要将bin添加到系统PATH

pdf2image应该也可以对指定区域进行截取,暂时还没详细研究其方法,因为已经找到更快的方法解决问题了,对比如下所示:

3、比较PyMuPDF和pdf2image

以下是对一份75页的PDF,输出DPI=96的时间性能对比,pdf2image使用的是默认线程数,下面的对比并没有设置多线程,使用多线程会快一点,当线程数设为5的时候,速度是9秒。

可以看出使用pyMuPDF_Fitz明显快一倍多,最终选取了这种方式。

4、Wand将PDF转换成图片

和pdf2image一样,wand都是包装接口(bindings),而实际进行转换的工具是ImageMagick.

Wind官网:

http://docs.wand-py.org/en/0.5.6/

ImageMagick官网:

https://imagemagick.org/script/download.php#windows

from wand.image import Imagefilename="somefile.pdf"with(Image(filename=filename, resolution=120)) as source:images = source.sequencepages = len(images)for i in range(pages):n = i + 1newfilename = filename[:-4] + str(n) + '.jpeg'Image(images[i]).save(filename=newfilename)

由于问题已经解决,而且性能也还不错,就没有具体去研究Wind这种方式了,感兴趣的可以去看看。

万水千山总是情,点个“在看”行不行

python pdf转图片 poppler_Python将PDF转成图片—PyMuPDF和pdf2image相关推荐

  1. python将视频按帧读取并转换成图片

    python将视频按帧读取并转换成图片 代码如下 from glob import glob import cv2 import tqdm import os video_path = glob(r' ...

  2. 读取json格式的图片、文字并保存成图片

    读取json格式的图片.文字并保存成图片 说明 从数据库中获取到图片.中文.英文信息后,将其合成json文件,图片格式为base64格式,需要将其转成二进制形式,然后将其保存成图片,将中文.英文信息保 ...

  3. html保存当前页面为图片,将html页面保存成图片,图片写入pdf的实现方法(推荐)

    需求是一个导出pdf的功能,多方奔走终于实现了,走了不少弯路,而且怀疑现在这个方法仍是弯的. 有个jsPDF 插件可以在前端直接生成pdf,很简便,但不支持IE. 前端: 首先引入  html2can ...

  4. python如何将图片的像素矩阵绘制成图片(python,matplotlib):TypeError: Invalid shape (1, 28, 28) for image data

    矩阵变成图片,这个问题使用(python , matplotlib ) 可以轻松实现. import matplotlib.pyplot as plt #使用格式 plt.imshow(x)#其中x为 ...

  5. python html转图片失真_html dom 转化成图片踩坑记(canvas toDataURL)

    需求 在开发过程中遇到这么一个需求,h5页面需要将一个html dom转化成图片,便于用户保存. 面向百度搜索第三方得 html2canvas 和 dom-to-image 两者在写这篇笔记之前在gi ...

  6. HTML表格无法保存图片,怎样将EXCLE表格或HTML保存为图片形式? | excle怎么存成图片的格式...

    怎样把图片中的表格转化到Excel 如何将EXCEL表格保存为图片(任何格式) 不能直接保存成图片,建议存成pdf 然后直接截图保存就行 个人偶尔会这么做,或者有时候页面不大的话,会直接qq截图保存 ...

  7. android base64 转图片,Android 中 Base64 转换成 图片

    场景 项目中有个功能是显示微信付款码,为了节省服务器存储,将图片以Base64的形式存储,客户端接收到后将Base64转换成图片并加载,但是不要存放大图,在网上看到的大多都是使用了一个java库(im ...

  8. Python二维码生成器:将网址转换成图片二维码

    二维码的普及无疑为进入网站以及浏览信息开辟了新的渠道,所以我利用Python强大的第三方库编写了转化程序,将一些常用的网址转化为二维码图片,用的时候会很方便:另外偷偷地告诉你一句呦,你还可以将一段文字 ...

  9. js大屏导出图片_js将canvas保存成图片并下载

    保存 var arr = [ {locations:[[0,0],[200,200],[0,400]],color:"red"}, {locations:[[0,0],[400,0 ...

最新文章

  1. Java项目:医院住院管理系统(java+SSM+jsp+mysql+maven)
  2. mac查看图片分辨率_Mac图像检查工具-Graphic Inspector
  3. java 实现栈_栈的Java实现
  4. mysql实现树形_Mysql实现树形递归查询
  5. Rainbond v5.1.2发布,微服务架构应用便捷管理和交付
  6. Tomcat(四):发布和优化
  7. 阿里ai布局开始_如何开始使用AI
  8. 在web开发中,为什么前端比后端更得到转行程序员的青睐?必看
  9. Python中替换元素
  10. mysql 分区 key 写法_mysql数据库KEY分区用法
  11. 1.swoole 简介
  12. java动态代理和Cglib动态代理的区别和使用
  13. 这家初创公司用端到端安全保护物联网设备
  14. 景区门票怎么在线上渠道分销?
  15. 计算机无法删除ie,Win7系统IE11 IE10 IE9强制卸载工具方法(解决IE无法卸载)
  16. 国产Linux系统deepin 小白双系统安装详细教程+笔记本双显卡处理设置+使用体验
  17. DDOS攻击如何防御
  18. dz3 php post 登录,如何在调用discuz接口中传递登录状态
  19. 老鱼Python数据分析——篇十四:读取“选股宝”的热点板块信息并存为excel文件
  20. (一)关于POE供电定义以及级别划分,如何测试网线是否满足相关标准?

热门文章

  1. 图片折腾的经历——文件批处理、爬虫、图片工具等
  2. CAD制图系列之椭圆画法标注
  3. CSS之控制所有p段落,首行缩进两个字符!...
  4. 微信小程序中实现——【音乐播放器】
  5. windows下安装github for windows和SourceTree
  6. 2021年Vector中国用户大会讲了啥
  7. matlab中的sparse函数使用
  8. 海上平台作业三维虚拟仿真
  9. Bandit:一款Python代码安全漏洞检测工具
  10. 如何实现大屏数字滚动效果