用pymupdf将pdf转为图片速度测试
读取pdf文件,将每页图片转为np.array格式,供paddleocr进行读取,此代码对转换速度进行了测试.
需要安装:paddleocr, pyinstrument, pymupdf,memory_profiler
收到pymupdf开发者回复,得到了更高效的方法, 使用pix.samples_mv可以直通内存(which is a memoryview to that internal area (without copying)) github链接 , 速度非常可观,相比之前的ms级加速到µs级,足足有3000倍
下面是测试结果:
images = []
pixs = [page.get_pixmap(dpi=300) for page in doc]
%timeit [np.frombuffer(pix.samples_mv, dtype=np.uint8).reshape((pix.height, pix.width, 3)) for pix in pixs]5.22 µs ± 188 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)%timeit [np.frombuffer(buffer=pix.samples, dtype=np.uint8).reshape((pix.height, pix.width, 3)) for pix in pixs]15.7 ms ± 77.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)%timeit [np.array(Image.frombytes("RGB", (pix.width, pix.height), pix.samples), dtype=np.uint8) for pix in pixs]105 ms ± 4.08 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)%timeit [np.array(Image.open(io.BytesIO(pix.pil_tobytes("JPEG")))) for pix in pixs]179 ms ± 3.03 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)%timeit [cv2.imdecode(np.frombuffer(bytearray(pix.pil_tobytes("JPEG")), dtype=np.uint8), cv2.IMREAD_COLOR) for pix in pixs]182 ms ± 2.07 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)%timeit [cv2.imdecode(np.frombuffer(pix.tobytes(), dtype='uint8'),cv2.IMREAD_COLOR) for pix in pixs]394 ms ± 1.36 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
测试平台是i7-8700,pdf是随便找的110KB文件,大文件速度会相对更慢一些,get_pixmap如果设置太大生成的图片会非常大
内存消耗也相对减少了一点:
%load_ext memory_profiler
%memit images = [np.frombuffer(pix.samples_mv, dtype=np.uint8).reshape((pix.height, pix.width, 3)) for pix in pixs]peak memory: 346.82 MiB, increment: 0.07 MiB
%memit [np.frombuffer(buffer=pix.samples, dtype=np.uint8).reshape((pix.height, pix.width, 3)) for pix in pixs]peak memory: 396.67 MiB, increment: 49.83 MiB
以下内容可以不看,下面是以前写的,测试不严谨
import ioimport cv2
import fitz
import numpy as np
from PIL import Image
from paddleocr import PaddleOCR
from pyinstrument import Profiler
from memory_profiler import profilepdf_file = "./测试文档.pdf"
doc = fitz.open(pdf_file)
ocr = PaddleOCR(use_angle_cls=True, use_gpu=False,lang="ch")# 测试函数时间
def test(func):def _call():profiler = Profiler()profiler.start()func()profiler.stop()print(profiler.output_text(unicode=True, color=True))return _call@test
# @profile
def test1():images = []for page in doc:pix = page.get_pixmap(dpi=300) # dpi=300是测试出来比较合适的大小,过大会导致图片过大image = Image.frombytes("RGB", (pix.width, pix.height), pix.samples)image = np.array(image, dtype=np.uint8)images.append(image)# [print(ocr.ocr(image)) for image in images] #确定images可以被ocr读取@test
# @profile
def test2():images = []for page in doc:pix = page.get_pixmap(dpi=300)image = np.frombuffer(buffer=pix.samples, dtype=np.uint8).reshape((pix.height, pix.width, 3))images.append(image)# [print(ocr.ocr(image)) for image in images]@test
# @profile
def test3():images = []for page in doc:pix = page.get_pixmap(dpi=300)image = cv2.imdecode(np.frombuffer(bytearray(pix.pil_tobytes("JPEG")), dtype=np.uint8), cv2.IMREAD_COLOR)images.append(image)# [print(ocr.ocr(image)) for image in images]@test
# @profile
def test4():images = []for page in doc:pix = page.get_pixmap(dpi=300)image = cv2.imdecode(np.frombuffer(pix.tobytes(), dtype='uint8'),cv2.IMREAD_COLOR)images.append(image)# [print(ocr.ocr(image)) for image in images]@test
# @profile
def test5():images = []for page in doc:pix = page.get_pixmap(dpi=300)image = np.array(Image.open(io.BytesIO(pix.pil_tobytes("JPEG"))))images.append(image)# [print(ocr.ocr(image)) for image in images]@test
# @profile
def test2_Comprehensions():imaegs = []pixs = [page.get_pixmap(dpi=300) for page in doc]images = [np.frombuffer(buffer=pix.samples, dtype=np.uint8).reshape((pix.height, pix.width, 3)) for pix in pixs ]# 列表推导式可以提高效率test1()
test2()
test3()
test4()
test5()
test2_Comprehensions()
时间测试结果:
_ ._ __/__ _ _ _ _ _/_ Recorded: 11:10:09 Samples: 112/_//_/// /_\ / //_// / //_'/ // Duration: 0.391 CPU time: 0.391
/ _/ v4.1.1Program: I:/ocr_test/性能测试.py0.381 _call 性能测试.py:17
├─ 0.374 test1 性能测试.py:27
│ ├─ 0.128 get_pixmap fitz\utils.py:812
│ │ [7 frames hidden] fitz, <built-in>
│ │ 0.125 DisplayList_get_pixmap <built-in>:0
│ ├─ 0.126 __array__ PIL\Image.py:705
│ │ [17 frames hidden] PIL, <built-in>
│ ├─ 0.056 frombytes PIL\Image.py:2788
│ │ [7 frames hidden] PIL, <built-in>
│ ├─ 0.038 array <built-in>:0
│ │ [2 frames hidden] <built-in>
│ ├─ 0.023 samples fitz\fitz.py:7468
│ │ [2 frames hidden] fitz
│ └─ 0.005 [self]
└─ 0.007 [self] _ ._ __/__ _ _ _ _ _/_ Recorded: 11:10:10 Samples: 15/_//_/// /_\ / //_// / //_'/ // Duration: 0.141 CPU time: 0.156
/ _/ v4.1.1Program: I:/ocr_test/性能测试.py0.141 _call 性能测试.py:17
├─ 0.136 test2 性能测试.py:38
│ ├─ 0.109 get_pixmap fitz\utils.py:812
│ │ [4 frames hidden] fitz, <built-in>
│ │ 0.109 DisplayList_get_pixmap <built-in>:0
│ ├─ 0.024 samples fitz\fitz.py:7468
│ │ [2 frames hidden] fitz
│ └─ 0.003 __del__ fitz\fitz.py:7494
│ [3 frames hidden] fitz, <built-in>
└─ 0.004 [self] _ ._ __/__ _ _ _ _ _/_ Recorded: 11:10:10 Samples: 56/_//_/// /_\ / //_// / //_'/ // Duration: 0.611 CPU time: 0.609
/ _/ v4.1.1Program: I:/ocr_test/性能测试.py0.607 _call 性能测试.py:17
└─ 0.607 test3 性能测试.py:48├─ 0.296 imdecode <built-in>:0│ [2 frames hidden] <built-in>├─ 0.196 pil_tobytes fitz\fitz.py:7279│ [33 frames hidden] fitz, PIL, <built-in>, ntpath, generi...└─ 0.113 get_pixmap fitz\utils.py:812[4 frames hidden] fitz, <built-in>_ ._ __/__ _ _ _ _ _/_ Recorded: 11:10:10 Samples: 21/_//_/// /_\ / //_// / //_'/ // Duration: 1.545 CPU time: 1.531
/ _/ v4.1.1
性能测试.py
1.540 _call 性能测试.py:17
└─ 1.535 test4 性能测试.py:58├─ 1.120 tobytes fitz\fitz.py:7146│ [4 frames hidden] fitz, <built-in>│ 1.120 Pixmap__tobytes <built-in>:0├─ 0.306 imdecode <built-in>:0│ [2 frames hidden] <built-in>└─ 0.109 get_pixmap fitz\utils.py:812[4 frames hidden] fitz, <built-in>_ ._ __/__ _ _ _ _ _/_ Recorded: 11:10:12 Samples: 146/_//_/// /_\ / //_// / //_'/ // Duration: 0.561 CPU time: 0.562
/ _/ v4.1.1Program: I:/ocr_test/性能测试.py0.567 _call 性能测试.py:17
└─ 0.567 test5 性能测试.py:68├─ 0.232 __array__ PIL\Image.py:705│ [13 frames hidden] PIL, <built-in>├─ 0.185 pil_tobytes fitz\fitz.py:7279│ [24 frames hidden] fitz, PIL, <built-in>, ntpath, generi...├─ 0.111 get_pixmap fitz\utils.py:812│ [4 frames hidden] fitz, <built-in>├─ 0.032 array <built-in>:0│ [2 frames hidden] <built-in>└─ 0.006 [self] _ ._ __/__ _ _ _ _ _/_ Recorded: 11:10:12 Samples: 16/_//_/// /_\ / //_// / //_'/ // Duration: 0.136 CPU time: 0.141
/ _/ v4.1.1Program: I:/ocr_test/性能测试.py0.143 _call 性能测试.py:17
├─ 0.131 test2_Comprehensions 性能测试.py:78
│ ├─ 0.109 <listcomp> 性能测试.py:82
│ │ └─ 0.109 get_pixmap fitz\utils.py:812
│ │ [4 frames hidden] fitz, <built-in>
│ │ 0.109 DisplayList_get_pixmap <built-in>:0
│ └─ 0.023 <listcomp> 性能测试.py:83
│ └─ 0.023 samples fitz\fitz.py:7468
│ [2 frames hidden] fitz
├─ 0.006 __del__ fitz\fitz.py:7494
│ [3 frames hidden] fitz, <built-in>
└─ 0.006 [self]
内存测试结果:
Filename: I:\ocr_test\性能测试.pyLine # Mem usage Increment Occurrences Line Contents
=============================================================30 290.2 MiB 290.2 MiB 1 @profile31 def test1():32 290.2 MiB 0.0 MiB 1 images = []33 449.1 MiB 0.1 MiB 6 for page in doc:34 424.0 MiB 29.5 MiB 5 pix = page.get_pixmap(dpi=300) # dpi=300是测试出来比较合适的大小,过大会导致图片过大35 457.2 MiB 166.1 MiB 5 image = Image.frombytes("RGB", (pix.width, pix.height), pix.samples)36 449.1 MiB -36.8 MiB 5 image = np.array(image, dtype=np.uint8)37 449.1 MiB 0.0 MiB 5 images.append(image)Filename: I:\ocr_test\性能测试.pyLine # Mem usage Increment Occurrences Line Contents
=============================================================41 299.7 MiB 299.7 MiB 1 @profile42 def test2():43 299.7 MiB 0.0 MiB 1 images = []44 449.3 MiB 0.0 MiB 6 for page in doc:45 424.4 MiB 25.1 MiB 5 pix = page.get_pixmap(dpi=300)46 449.3 MiB 124.5 MiB 5 image = np.frombuffer(buffer=pix.samples, dtype=np.uint8).reshape((pix.height, pix.width, 3))47 449.3 MiB 0.0 MiB 5 images.append(image)Filename: I:\ocr_test\性能测试.pyLine # Mem usage Increment Occurrences Line Contents
=============================================================51 299.9 MiB 299.9 MiB 1 @profile52 def test3():53 299.9 MiB 0.0 MiB 1 images = []54 716.0 MiB 0.0 MiB 6 for page in doc:55 657.8 MiB 124.6 MiB 5 pix = page.get_pixmap(dpi=300)56 716.0 MiB 291.5 MiB 5 image = cv2.imdecode(np.frombuffer(bytearray(pix.pil_tobytes("JPEG")), dtype=np.uint8), cv2.IMREAD_COLOR)57 716.0 MiB 0.0 MiB 5 images.append(image)Filename: I:\ocr_test\性能测试.pyLine # Mem usage Increment Occurrences Line Contents
=============================================================61 300.9 MiB 300.9 MiB 1 @profile62 def test4():63 300.9 MiB 0.0 MiB 1 images = []64 450.3 MiB 0.0 MiB 6 for page in doc:65 425.6 MiB 24.8 MiB 5 pix = page.get_pixmap(dpi=300)66 450.3 MiB 124.6 MiB 5 image = cv2.imdecode(np.frombuffer(pix.tobytes(), dtype='uint8'),cv2.IMREAD_COLOR)67 450.3 MiB 0.0 MiB 5 images.append(image)Filename: I:\ocr_test\性能测试.pyLine # Mem usage Increment Occurrences Line Contents
=============================================================71 300.9 MiB 300.9 MiB 1 @profile72 def test5():73 300.9 MiB 0.0 MiB 1 images = []74 716.3 MiB 0.0 MiB 6 for page in doc:75 657.1 MiB 124.7 MiB 5 pix = page.get_pixmap(dpi=300)76 716.3 MiB 290.7 MiB 5 image = np.array(Image.open(io.BytesIO(pix.pil_tobytes("JPEG"))))77 716.3 MiB 0.0 MiB 5 images.append(image)Filename: I:\ocr_test\性能测试.pyLine # Mem usage Increment Occurrences Line Contents
=============================================================81 301.2 MiB 301.2 MiB 1 @profile82 def test2_Comprehensions():83 301.2 MiB 0.0 MiB 1 imaegs = []84 425.9 MiB 124.7 MiB 6 def a(pix):85 450.8 MiB 124.5 MiB 5 return np.frombuffer(buffer=pix.samples, dtype=np.uint8).reshape((pix.height, pix.width, 3))86 425.9 MiB -124.5 MiB 8 images = [a(page.get_pixmap(dpi=300)) for page in doc]
可以看出,test4方法最慢,test3方法占用内存最多,test2方法最优秀,有最快的速度和最少的内存占用,如果使用列表推导式理论上还能加速和减少内存使用,速度提升有限
测试过程中还发现如果使用Image.open可能会过大导致PIL.Image.DecompressionBombError
用pymupdf将pdf转为图片速度测试相关推荐
- 用pdfjs 在 node服务端将pdf转为图片
原文链接: 用pdfjs 在 node服务端将pdf转为图片 上一篇: puppeteer pdf 转图片 [不建议使用] 下一篇: 用dom-to-image 截取B站弹幕 [做了一半] 需要使用c ...
- Python怎么将pdf转为图片?Python如何实现pdf文件转图片
而pdf则是用来保存一些内容已经确定好的数据,因为pdf是无法直接修改内容的,所以也会经常将pdf转为图片来保存.本文就将会来介绍一下pdf转图片的方法,往下看看吧. 1.pdf转图片的话主要实现所需 ...
- 使用js在线将pdf转为图片
纯前端js,不用后端代码,即可将pdf转为图片. 在线demo地址 index.html <!DOCTYPE html> <html><head><meta ...
- pdf转为图片的三种简单的方法
现在越来越多的工作和学习都是通过电子文档来完成的,pdf是其中一种最常见的文档格式之一,它的排版固定.浏览直观.舒适,不容易出错,非常方便使用.但是小伙伴们在使用pdf文档的时候有没有遇到过这种情况, ...
- 通过Python的pdfplumber库将pdf转为图片
文章目录 前言 一.pdfplumber库是什么? 二.安装pdfplumber库 三.查看pdfplumber库版本 四.pdf素材 五.将pdf转为图片 1.引入库 2.定义pdf路径 3.打开P ...
- Python 利用pymupdf将pdf转换为图片并拆分,后通过PIL合并生成一张图片
文章主要内容主要参考几篇文章并合并在一起的,文章链接依次如下,第二和第三的文章链接是从第一篇文章找到的: (1).https://blog.csdn.net/qq_25115281/article/d ...
- java pdf转图片 pdfbox_JAVA基于PDF box将PDF转为图片
在一项目中用到,本身我是.NET的,团队中有用到JAVA,故此我处理这个功能,记录以下备用. 1.引用:fontbox-2.0.16.jar.pdfbox-app-2.0.16.jar 版本一定要正确 ...
- C# asp.net .netcore 单层和双层PDF转为图片
针对客户需求,首先需要实现PDF转图片,经科普,两种不同的PDF分别指:单层:以图片为基础的PDF文档,鼠标滑动无法进行勾选.双层:文字会浮于底层的PDF之上,而且鼠标滑动可见勾选的信息被框选. 单层 ...
- c++ 一键将pdf转为图片
pdf内容转为图片 效果如下所示: 部分代码如下: void CPdfConvertBmpDlg::OnBnClickedButton1() { CFileDialog pCFileDialo ...
最新文章
- Linux下的USB总线驱动 mouse
- 在docker中安装RabbitMQ
- java中如何检查字符串都是数字_如何在Java中检查字符串是否为数字?
- 找到最大回文子串_使用O(1)空间复杂度找到最大的回文子串
- 少儿编程几种语言_您使用了几种编程语言?
- linux嵌入式物联网_嵌入式Linux如何加速物联网发展
- C++之++操作符重载
- 学习就是一件要耐的住寂寞放的下欲望舍的得享乐的事
- Android新建一个activty
- 7个设计模式的基本原则
- Spark数据分析技术学习笔记(二)——DataFrame使用
- Linux Kickstart无人值守安装
- 五种酷炫代码雨的源代码
- Vue后台管理系统项目总结
- 洛必达法则及极限问题总结
- python初学者-计算小于100的最大素数
- android跳到自带浏览器打开pdf
- 深度学习之图像分类(二十五)-- S2MLPv2 网络详解
- MT9V034摄像头学习笔记(二)
- 用咖啡为模型解释一下装饰者模式