直接上代码,不过要先安装pymupdf,使用pymupdf中的fitz导出PDF中的图片
pip install pymupdf
代码:
import fitz
import re
import os
import sys
import _thread
import threading
import time
# PDF转图像函数
def pdf2image(path, pic_path):
checkIM = r"/Subtype(?= */Image)"
pdf = fitz.open(path)
lenXREF = pdf.xref_length()
count = 1
imgThreadList = []
# 创建目录
if not os.path.exists(pic_path):
os.mkdir(pic_path)
# 遍历所有对象
for i in range(1, lenXREF):
text = pdf.xref_object(i)
isImage = re.search(checkIM, text)
if not isImage:
continue
print('开始转换 ' + str(i) + '/' + str(lenXREF))
pix = fitz.Pixmap(pdf, i)
# 判断图像大小
if pix.w < 100 or pix.h < 100:
print('图像过小(' + str(pix.w()) + ',' + str(pix.h()) + ')')
continue
# 图像文件路径名称
new_name = os.path.join(pic_path, f"img_{count}.png")
clock1 = time.monotonic()
# 直接保存
#pix.writePNG(new_name) #废弃
pix.save(new_name)
clock2 = time.monotonic()
print('转换完成(time:' + str(clock2-clock1) + ') ' + str(i) + '/' + str(lenXREF) + ' 图片 -> ' + str(count) + ': ' + new_name)
count += 1
pix = None
#####################################################################################################
if __name__=='__main__':
file_path = r'5.pdf' # PDF 文件路径
dir_path = r'pics' # 存放图片的文件夹
# 文件当前路径
print(os.path.split(sys.argv[0])[0])
print(os.path.split(os.path.realpath(__file__))[0])
curPath = os.path.split(os.path.realpath(__file__))[0]
# 开始转换指定文件
pdf2image(os.path.join(curPath, file_path), os.path.join(curPath, dir_path))
多线程版,实际尝试了一下似乎没什么效果,暂时只保留代码
import fitz
import re
import os
import sys
import _thread
import threading
import time
# 自定义保存图片线程类
class myThread (threading.Thread):
def __init__(self, pdfImg, imgFileName):
threading.Thread.__init__(self)
self.pdfImg = pdfImg
self.imgFileName = imgFileName
def run(self):
print ("开始线程:" + self.imgFileName)
time.sleep(1)
self.pdfImg.save(self.imgFileName)
print ("退出线程:" + self.imgFileName)
# 保存图像函数
def mysaveImg(pdfImg, imgFileName):
time.sleep(1)
print ("开始保存图片:" + imgFileName)
pdfImg.save(imgFileName)
print ("结束保存图片:" + imgFileName)
# PDF转图像函数
def pdf2image(path, pic_path):
checkIM = r"/Subtype(?= */Image)"
pdf = fitz.open(path)
lenXREF = pdf.xref_length()
count = 1
imgThreadList = []
# 创建目录
if not os.path.exists(pic_path):
os.mkdir(pic_path)
# 遍历所有对象
for i in range(1, lenXREF):
text = pdf.xref_object(i)
isImage = re.search(checkIM, text)
if not isImage:
continue
print('开始转换 ' + str(i) + '/' + str(lenXREF))
pix = fitz.Pixmap(pdf, i)
# 判断图像大小
if pix.w < 100 or pix.h < 100:
print('图像过小(' + str(pix.w()) + ',' + str(pix.h()) + ')')
continue
# 图像文件路径名称
new_name = os.path.join(pic_path, f"img_{count}.png")
clock1 = time.monotonic()
# 直接保存
#pix.writePNG(new_name) #废弃
#pix.save(new_name)
# 虽然使用了多线程,但是保存还是一张一张的保存,原因未知
#启动一个线程处理
#thread1 = None
#thread1 = myThread(pix, new_name)
#thread1.start()
#thread1 = None
# 线程放入一个列表,等会一起启动
#imgThreadList.append(myThread(pix, new_name))
# 使用线程函数处理
_thread.start_new_thread( mysaveImg, (pix, new_name, ) )
clock2 = time.monotonic()
print('转换完成(time:' + str(clock2-clock1) + ') ' + str(i) + '/' + str(lenXREF) + ' 图片 -> ' + str(count) + ': ' + new_name)
count += 1
pix = None
# 启动所有线程
#for imgThread in imgThreadList:
# imgThread.start()
#####################################################################################################
if __name__=='__main__':
file_path = r'5.pdf' # PDF 文件路径
dir_path = r'5556' # 存放图片的文件夹
# 文件当前路径
print(os.path.split(sys.argv[0])[0])
print(os.path.split(os.path.realpath(__file__))[0])
curPath = os.path.split(os.path.realpath(__file__))[0]
# 开始转换指定文件
#pdf2image(os.path.join(curPath, file_path), os.path.join(curPath, dir_path))
# 转换多个文件
for index in range(1, 5+1, 1):
print('文件:' + os.path.join(curPath, str(index)) + '.pdf')
pdf2image(os.path.join(curPath, str(index)) + '.pdf', os.path.join(curPath, str(index)))
参考:
https://blog.csdn.net/weixin_46737755/article/details/113085763
https://blog.csdn.net/qq_15969343/article/details/81673302
https://blog.csdn.net/weixin_46737755/article/details/113085763
|