关于python处理PDF文件的第三方库fitz(pyMupdf)以及opencv-python imdecode和imencode的使用困惑

因为项目需求,我需要将PDF文件的每页转成图片数组,再将每页的图片数组还原合并为PDF文件(中间文件不保存):

import numpy as np
import fitz
import cv2


def generate_pixmap_pdf(input_pdf: str, output_pdf: str, dpi: int) -> None:

    original_doc = fitz.Document(input_pdf)
    pixmap_doc = fitz.Document()

    for p in range(original_doc.page_count):
        # 先将每一页转为Pixmap,再把Pixmap变为ndarray.
        pre_pixmap = original_doc[p].get_pixmap(dpi=dpi, alpha=False)
        pre_buffer = np.frombuffer(pixmap.tobytes(output="png"), dtype=np.ubyte)
        image = cv2.imdecode(pre_buffer, cv2.IMREAD_UNCHANGED)
        # ndarray转为Pixmap,再插入到Document.
        post_buffer = cv2.imencode(".png", image)[1]
        post_pixmap = fitz.Pixmap(post_buffer.tobytes())
        pixmap_doc.insert_file(post_pixmap)

    # 保存为PDF文档.
    pixmap_doc.save(output_pdf)
    pixmap_doc.close()
    original_doc.close()


if __name__ == "__main__":
    input_file = r"..\paper.pdf"
    output_file = r"..\paper_.pdf"
    dpi = 96
    generate_pixmap_pdf(input_file, output_file, dpi)

困惑①:

每一页的pre_buffer和post_buffer并不一致

        ...
        pre_buffer = np.frombuffer(pixmap.tobytes(output="png"), dtype=np.ubyte)
        image = cv2.imdecode(pre_buffer, cv2.IMREAD_UNCHANGED)
        post_buffer = cv2.imencode(".png", image)[1]
        ...

我个人认为缓冲中的memory经过imdecode解码后,再经过imencode编码得到的memory与原来的一致,但是以上代码经过验证后二者有出入。也尝试过调整pixmap.tobytes和cv2.imencode的参数,但是并没有得到pre_buffer和post_buffer完全一致的结果。可能是我先入为主。

困惑②:

在fitz库中生成dpi=96的pixmap是否具有特殊性,或者说96dpi在图像或者pixmap中是什么特殊的常数?

    for i in range(original_doc.page_count):
        pre_pixmap = original_doc[p].get_pixmap(dpi=96, alpha=False)
        ...

我知道fitz库的Pixmap有点类似截图的效果,也就是说从原始的PDF文件在generate_pixmap_pdf()处理后生成的第一代PDF文件的清晰度会降低,所以以此推测,连续多次在相同的dpi条件下对子代PDF文件调用generate_pixmap_pdf()函数生成的第二代、第三代…第n代PDF文件的清晰度应该是逐步下降,最终会产生信息丢失(清晰度也可能会提高,但对应的文件大小也会增加)。

但是实际上也是有出入的:
Ⅰ. Pixmap不经过imdecode和imencode处理直接插入新的Document当中生成新的子代PDF文件只有在原始文件生成一代文件的情况下清晰度才会降低,其他后代PDF文件与前一代PDF文件相比没有变化,并且dpi的取值没有影响(这里以PDF文件大小的变化等效于PDF文件清晰度的变化);

    for j in range(original_doc.page_count):
        pixmap = original_doc[j].get_pixmap(dpi=dpi, alpha=False)
        pixmap_doc.insert_file(pixmap)

Ⅱ. Pixmap经过imdecode和imencode处理后,也就是pre_buffer与post_buffer、pre_pixmap与post_pixmap不一致的情况下,(目前得到的结果)只有dpi的值为96时,才会发生Ⅰ的情况。而当dpi < 96时,子代PDF文件的清晰度和文件大小逐步降低;当dpi > 96时,子代PDF文件的清晰度和文件大小逐步增加。

但是奈何一直没找到dpi=96有什么特殊性。

请教大佬们帮助解惑,非常感谢!

讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!