在贴吧中有许多的PDF转图片类似算法,但好多算法没法控制自己转出图片的质量,若是本来PDF就是扫描版的,转出后则会有许多的毛边,放大后不清晰。为解决此类问题进行多次尝试最终完成一个交过不错的版本。
1.原理说明:
使用fitz库,可以读取文件夹下的所有PDF,自动全部按照PDF名字转图片
PDFfiles = glob.glob("PDF文件\\*.pdf")
是读取文件夹下的所有PDF,这里的glob是Python自带的库,不需要安装,直接引用就行。
for pg in range(PDFdoc.pageCount):
这里可以自动的计算出PDF包含有多少页,也可以自己控制转换页码的范围(自己写一个配置文件读取转换范围即可)
zoom_x = 5 #水平方向
zoom_y = 5 #垂直方向
通过这个地方来调节质量,数值越大转换的图像质量越好,但是他们不能超过一定的数值,一般这两个方向的数值是一样的,这个数值为5的时候照片大小也就0.5M大小,这里的数值*360差不多就是实际照片的分辨率。
当我把这两个数调节到50的话,PDF转换出的图片每张为17964*27636存储为17.6MB大小,
当我把这两个数调节到20的话,PDF转换出的图片每张为7186*11055存储为1.84MB大小,
img = img_Brightness_contrast(pix)
img = img_improve2(img)
通过这两个函数进行图片的增强,增加图片给的对比度和亮度、饱和度
2.效果展示
转换前的PDF
转换后的图片,放大一定范围内不会出现毛边。
import fitz
import glob
import numpy as np
import cv2
def img_improve2(image):
b, g, r = cv2.split(image) # 拆
bH = cv2.equalizeHist(b) # 对三个通道图进行直方图均衡化
gH = cv2.equalizeHist(g)
rH = cv2.equalizeHist(r)
result = cv2.merge([bH, gH, rH]) # 合
res = np.hstack((image, result))
threshold = 50 # 设立一个阈值
h, w = image.shape[:2]
result[np.where((result[:,:,0] > threshold) & (result[:,:,1] > threshold) & (result[:,:,2] > threshold))] = [255, 255, 255] # 如果大于阈值就赋予白色,保证黑色留下
return result
def img_Brightness_contrast(pix):
img_array = np.frombuffer(pix.samples, dtype=np.uint8).reshape(pix.height, pix.width, 3)
img = cv2.cvtColor(img_array, cv2.COLOR_RGB2BGR)
bri_mean = np.mean(img)
Brightness = 2.0 # 对比度
contrast = 110 # 亮度.
img_a = Brightness * (img-bri_mean) + contrast + bri_mean
img_a = np.clip(img_a, 0, 255).astype(np.uint8)
return img_a
image_path = "D:/jupyter/百度飞浆的OCR识别/PDF/" #存放图片的文件夹
PDFfiles = glob.glob("D:/jupyter/百度飞浆的OCR识别/PDF/JavaScript.pdf") #获取所有pdf文件的文件名
# for PDFfile in PDFfiles: #遍历所有PDF文件
# image_path = "图片\\" #存放图片的文件夹
# PDFfiles = glob.glob("PDF文件\\*.pdf") #获取所有pdf文件的文件名
import time
start = time.time()
for PDFfile in PDFfiles: #遍历所有PDF文件
PDFdoc = fitz.open(PDFfile) #读取PDF文件
folder_name = PDFfile.split("\\")[-1].split(".")[0] #按源文件名新建文件夹
for pg in range(PDFdoc.pageCount): #根据PDF的页数,按页提取图片
page = PDFdoc[pg]
#增强图片分辨率
zoom_x = 5 #水平方向
zoom_y = 5 #垂直方向
mat = fitz.Matrix(zoom_x, zoom_y)
pix = page.getPixmap(matrix=mat)
# 将fitz中的图片数据转换为OpenCV的图像格式
img = img_Brightness_contrast(pix)
img = img_improve2(img)
end = time.time()
running_time = end - start
print("程序运行时间:", running_time)
#按原PDF名称新建文件夹并按顺序保存图片
# if not os.path.exists(image_path+folder_name):#判断文件夹是否已存在
# os.makedirs(image_path+folder_name)#不存在则新建,存在就跳过这行
print(folder_name + "{}cv.png".format(str(pg+1)))
# cv2.imwrite(image_path+folder_name + "{}cv.png".format(str(pg+1)), img)
pix.writeImage(folder_name + "{}.png".format(str(pg+1))) #按PDF中的页面顺序命名并保存图片