日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python将PDF转成图片—PyMuPDF和pdf2image

發布時間:2024/1/8 python 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python将PDF转成图片—PyMuPDF和pdf2image 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:在最近的測試中遇到一個與PDF相關的測試需求,其中有一個過程是將PDF轉換成圖片,然后對圖片進行測試。

粗略的試了好幾種方式,其中語言嘗試了Python和Java,總體而言所找到的Python方式相對比Java更快一些,更簡單一些。

下面首先分享一下Python將PDF轉換成圖片,Java后續有時間在進行分享。

需求:我需要先將PDF轉換成為PNG圖片,并截取圖片的一部分存儲,然后作為測試目標進行測試。

操作:

1、PDF轉PNG圖片

2、對PNG圖片進行指定區域截圖,在另存到指定文件夾下

針對截圖此處所找到的方法如上一篇博客:
Python圖片裁剪的兩種方式——Pillow和OpenCV

1、PyMuPDF將PDF轉換成圖片

import sys, fitz import os import 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, fitz import os import 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_bytes import tempfile from 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?Image filename="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转成图片—PyMuPDF和pdf2image的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。