由于某些不可避免的原因,需要在某些网站上传一些.pdf
文件,那些奇葩的网站对文件大小做了限制,所以需要对较大的.pdf
文件进行压缩处理,而一般免费的阅读器都不能随意的压缩(要么需要你交很高的会员费),好在这些任务python
都可以很好的处理。
本文编写了相关的python
脚本,有需要的可以参考。
一些说明
本文的内容参考了其他博客(如此处),但对其中脚本进行了一些修改。
我使用的操作系统是MacOS
,如果是其他系统,可能需要你自己动手进行一些修改。
安装PyMuPDF
首先我们安装PyMuPDF
包,如下:
pip install pymupdf=1.20.2
|
上述命令指定了版本,是为了避免因为版本不同导致的问题。
压缩脚本
编写的脚本如下:
import os import shutil import fitz from tqdm import tqdm
def pdf2pic(file_root, filename: str, out_name: str = None, zoom=50): """ 将pdf逐页转化为png图片 :param file_root: 文件根目录 :param filename: 文件名,不带后缀 :param out_name: 输出文件名,默认为 filename+'_new',用以存储pdf转化生成的 'png' 文件 :param zoom: 缩小的百分比比例 """ if '.pdf' in filename: filename = filename.split('.pdf')[0] file = f"{file_root}/{filename}.pdf".replace('//', '/') if not os.path.exists(file): raise FileExistsError(f"File {file} not exists") out_name = out_name or f"{filename}_new" out_file = f"{file_root}/{out_name}".replace('//', '/') doc_f = fitz.Document(file) if os.path.exists(out_file): shutil.rmtree(out_file) os.mkdir(out_file) tq_t = tqdm(range(doc_f.page_count)) for pg in tq_t: tq_t.set_description(f"Pdf to png. Page {pg}...") page = doc_f.load_page(pg) zoom = int(zoom) lurl = f"{out_file}/{pg}.png" trans = fitz.Matrix(zoom / 100.0, zoom / 100.0) pm = page.get_pixmap(matrix=trans, alpha=False) pm.save(lurl) doc_f.close()
def pic2pdf(file_root, pic_filename, pdf_name: str = None): """ 将图片合并成pdf :param file_root: 文件存储的根目录 :param pic_filename: 图片保存的目录名 :param pdf_name: 转出的pdf名称,若不指定则采用pic_filename加上后缀'.pdf' """ pic_path = f"{file_root}/{pic_filename}".replace('//', '/') pdf_name = pdf_name or pic_filename pdf_path = f"{file_root}/{pdf_name}.pdf".replace('//', '/') if not os.path.exists(pic_path): raise FileExistsError(f"pic_path {pic_path} not exists.") if os.path.exists(pdf_path): os.remove(pdf_path) pics = os.listdir(pic_path) pics = [file for file in pics if '.png' in file] doc = fitz.Document() tq_t = tqdm(range(len(pics))) for pg in tq_t: tq_t.set_description(f"Pic to pdf, processing {pg}...") img = f'{pic_path}/{pg}.png' imgdoc = fitz.Document(img) pdfbytes = imgdoc.convert_to_pdf() imgpdf = fitz.Document(stream=pdfbytes, filetype='pdf') doc.insert_pdf(imgpdf) doc.save(pdf_path) doc.close() shutil.rmtree(pic_path)
def pdf_zoom(file_path, out_name=None, zoom=50): """ 将pdf缩小 :param file_path: 待转换pdf文件的绝对路径 :param out_name: 输出的pdf名称(不带后缀) :param zoom: 缩小的百分比 """ file_root, filename = os.path.split(file_path) pdf2pic(file_root=file_root, filename=filename, out_name=out_name, zoom=zoom) pic_filename = out_name or f"{filename.split('.pdf')[0]}_new" pic2pdf(file_root=file_root, pic_filename=pic_filename, pdf_name=out_name) print(f"Finished to reduce size of {filename}, the new file is {pic_filename}.pdf")
if __name__ == "__main__": pdf_zoom(file_path='/path/to/file/xxx.pdf', zoom=55)
|
上述脚本中还用到了tqdm
包,用来显示进度条;fitz
为pymupdf
包下的内容。
执行的时候:
将最后一行的file_path
参数的赋值改成自己需要转换文件的路径(需要绝对路径)即可。
缩小的百分比通过zoom
参数来控制调节,其可以取值范围为\([0, 100]\)。
先生成一个临时的图片文件夹(需要转换的.pdf
文件根目录下),在完成转化后、该图片文件夹会被自动删除。
最后输出的清晰度会降低。这是因为没有做任何优化,仅仅是通过降低清晰度来缩小文件大小的。