import sys, fitz, os, datetime
import time
from PIL import Image
import numpy as np
'''
fitz库是什么,它是pymupdf中的一个模块,操作PDF非常舒服,只需要pip安装即可:
pip install pymupdf
'''
def pyMuPDF_fitz(pdfPath, imagePath, zoomNum):
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=96
# zoom_x = 1.33333333 #(1.33333333-->1056x816) (2-->1584x1224)
zoom_x = zoomNum #(1.33333333-->1056x816) (2-->1584x1224)
# zoom_y = 1.33333333
zoom_y = zoomNum
mat = fitz.Matrix(zoom_x, zoom_y).preRotate(rotate)
pix = page.getPixmap(matrix=mat, alpha=False)
if not os.path.exists(imagePath):#判断存放图片的文件夹是否存在
os.makedirs(imagePath) # 若图片文件夹不存在就创建
if pg < 10:
pg_str = '00' + str(pg)
elif 10 <= pg <100:
pg_str = '0' + str(pg)
else:
pg_str = str(pg)
pix.writePNG(imagePath+'/'+'%s.png' % pg_str)#将图片写入指定的文件夹内
endTime_pdf2img = datetime.datetime.now()#结束时间
print('pdf2img时间=',(endTime_pdf2img - startTime_pdf2img).seconds,'秒')
def pyMuBinaryzation(binaryzationpath):
startTime_pdfbinaryzation = datetime.datetime.now()#开始时间
file_list = os.listdir(binaryzationpath)
pic_name = []
for x in file_list:
if "jpg" in x or 'png' in x or 'jpeg' in x:
pic_name.append(x)
for i in pic_name:
image = Image.open(binaryzationpath + '/' + i)
new_file_name = binaryzationpath + '/' + i
picArray = np.array(image) # 解析图片成 numpy矩阵
'''
以下是加深150以下的 并且不相等的
'''
red_data = picArray[..., 0]
green_data = picArray[..., 1]
blue_data = picArray[..., 2]
red_green = red_data - green_data
red_blue = red_data - blue_data
red_150_1 = np.int64(red_data < 160)
green_150_1 = np.int64(green_data < 150)
blue_150_1 = np.int64(blue_data < 150)
red_green_1 = np.int64(red_green != 0)
black_150_index = np.where(red_150_1 + green_150_1 + blue_150_1 + red_green_1 == 4)
picArray[black_150_index] = [0, 0, 0]
'''
以下是加深100以下 并且相等值的
'''
red_data = picArray[..., 0]
green_data = picArray[..., 1]
blue_data = picArray[..., 2]
red_green = red_data - green_data
red_blue = red_data - blue_data
red_100_1 = np.int64(red_data < 100)
red_green_100 = np.int64(red_green == 0)
red_blue_100 = np.int64(red_blue == 0)
black_100_index = np.where(red_100_1 + red_green_100 + red_blue_100 == 3)
picArray[black_100_index] = [0, 0, 0]
'''
以下是红色情况的去除
'''
red_data = picArray[..., 0]
green_data = picArray[..., 1]
blue_data = picArray[..., 2]
red_green = red_data - green_data
red_blue = red_data - blue_data
red_green1 = np.int64(red_green > 10)
red_blue1 = np.int64(red_blue > 10)
red_index = np.where(red_green1 + red_blue1 == 2)
picArray[red_index] = [255, 255, 255]
'''
以下是去除200以上的
'''
red_data = picArray[..., 0]
green_data = picArray[..., 1]
blue_data = picArray[..., 2]
red_green = red_data - green_data
red_blue = red_data - blue_data
red_200_1 = np.int64(red_data > 200)
green_200_1 = np.int64(green_data > 200)
blue_200_1 = np.int64(blue_data > 200)
white_200_index = np.where(red_200_1 + green_200_1 + blue_200_1 == 3)
picArray[white_200_index] = [255, 255, 255]
im = Image.fromarray(picArray)
im.save(new_file_name)
endTime_pdfbinaryzation = datetime.datetime.now() # 结束时间
print('pdfpdfbinaryzation时间=',(endTime_pdfbinaryzation - startTime_pdfbinaryzation).seconds,'秒')
def pyMuPicToPdf(picDir,outfilepath):
startTime_PicToPdf = datetime.datetime.now() # 开始时间
file_list = os.listdir(picDir)
pic_name = []
im_list = []
print(file_list)
for x in file_list:
if "jpg" in x or 'png' in x or 'jpeg' in x:
pic_name.append(x)
pic_name.sort()
im1 = Image.open(picDir + '/' + pic_name[0])
pic_name.pop(0)
for i in pic_name:
img = Image.open(picDir + '/' + i)
# im_list.append(img)
if img.mode == "RGBA":
img = img.convert('RGB')
im_list.append(img)
else:
im_list.append(img)
im1.save(outfilepath, "PDF", resolution=100.0, save_all=True, append_images=im_list)
endTime_PicToPdf = datetime.datetime.now() # 结束时间
print('PicToPdf时间=', (endTime_PicToPdf - startTime_PicToPdf).seconds, '秒')
def deleteDir(path):
try:
for i in os.listdir(path):
path_file = os.path.join(path, i)
if os.path.isfile(path_file):
os.remove(path_file)
if os.path.exists(path): # 如果文件夹
# 删除文件,可使用以下两种方法。
os.rmdir(path)
# os.unlink(path)
else:
print('no such file:%s' % path) # 则返回文件不存在
except Exception as e:
print(e)
def mainProcess(fileName,outfilepath='',zoomNum=2):
'''
主函数入口
:param fileName:需要去章的文件路径
:param outfilepath:需要输出的文件路径,包括文件名,默认在同目录下生成 xxx_out.pdf 文件
:param zoomNum:转换成图片的比例,影响运行速度,数值越大,去章效果越好,执行时间越长,默认为2
:return:
'''
startTime = datetime.datetime.now() # 开始时间
(filepath, tempfilename) = os.path.split(fileName) # 解析fileName
(filename, extension) = os.path.splitext(tempfilename) # 解析文件名 文件类型
if not outfilepath:
outfilepath = filepath + '/' +filename + '_out' + extension
outdir = filepath + '/' + filename
pyMuPDF_fitz(fileName,outdir,zoomNum) # 将pdf文件解析出图片
pyMuBinaryzation(outdir) # 对图片进行去章
pyMuPicToPdf(outdir,outfilepath) # 将图片合成pdf
deleteDir(outdir) # 删除图片文件夹
endTime = datetime.datetime.now() # 结束时间
print('总耗时=', (endTime - startTime).seconds, '秒')
if __name__ == '__main__':
# fileName = r'C:\Users\Administrator\Desktop\副本.pdf'
fileName = r'C:\Users\Administrator\Desktop\source(1).pdf'
mainProcess(fileName) # 入口函数