【问题标题】:Using tempfile to insert barcodes into PDF file使用 tempfile 将条形码插入 PDF 文件
【发布时间】:2022-11-26 21:27:37
【问题描述】:

我正在做一个项目,我需要使用一个包含 100,000 张图像的大型 PDF 文件,我需要在每个第 n 页(条件依赖)上插入一个自定义/可变条形码。

每次插入条形码的内容都会发生变化,对于这个例子,我们只说基于迭代。

我过去曾使用 PyMuPDF 来处理 PDF,包括插入图像。我已经测试过在保存到文件时插入条形码,没有任何问题。

我过去曾使用 Treepoem 根据需要以小得多的规模生成自定义条形码。

(这仍处于计划/概念验证阶段)所以我担心的是,如果我要在更大范围内进行此操作,我将受到磁盘读/写速度的限制。

我知道 python 有一个我从未使用过的临时文件库。我试图利用它来生成条形码并将其保存到内存中的临时文件中,然后将它们从内存中插入到 PDF 文件中,而不是从磁盘/文件中插入。

我已经测试并确认生成条形码并将其保存到文件允许我根据需要插入到 PDF 文件中。下面的例子:

import fitz
import treepoem

barcode_file = treepoem.generate_barcode(
    barcode_type='datamatrixrectangular',
    data='10000010'
).convert('1').save('barcode_file.jpg') # Convert('1') forces monochrome, reducing file size.

pdf_file = fitz.open()  # Creating a new file for this example.
pdf_file.new_page()  # Inserting a new blank page.
page = pdf_file[0]

rect = fitz.Rect(70, 155, 200, 230)  # Generic area defined, required to insert barcode into. (x0, y0, x1, y1)

page.insert_image(rect, filename='barcode_file.jpg')
pdf_file.save('example_pdf_with_barcode.pdf')

当尝试实现 tempfile 以删除保存到文件时,我不确定在哪里使用它。

我尝试创建一个新的临时文件对象,将条形码图像插入其中。

import fitz
import tempfile
import treepoem

barcode_contents = treepoem.generate_barcode(
    barcode_type='datamatrixrectangular',
    data='10000010'
).convert('1')

barcode_tempfile = tempfile.TemporaryFile()
barcode_tempfile.write(b'{barcode_contents}')  # Like f-string, with binary?
barcode_tempfile.seek(0)  # Required, not understood.

pdf_file = fitz.open()  # Creating a new file for this example.
pdf_file.new_page()  # Inserting a new blank page.
page = pdf_file[0]

rect = fitz.Rect(70, 155, 200, 230)  # Generic area defined, required to insert barcode into. (x0, y0, x1, y1)

page.insert_image(rect, filename=barcode_tempfile)
pdf_file.save('example_pdf_with_barcode.pdf')

它返回基于权限的错误:

  File "<redacted>\example.py", line 20, in <module>
    page.insert_image(rect, filename=barcode_tempfile)
  File "<redacted>\venv\Lib\site-packages\fitz\utils.py", line 352, in insert_image
    xref, digests = page._insert_image(
                    ^^^^^^^^^^^^^^^^^^^
  File "<redacted>\venv\Lib\site-packages\fitz\fitz.py", line 6520, in _insert_image
    return _fitz.Page__insert_image(self, filename, pixmap, stream, imask, clip, overlay, rotate, keep_proportion, oc, width, height, xref, alpha, _imgname, digests)
           
RuntimeError: cannot open <redacted>\AppData\Local\Temp\tmpr_98wni9: Permission denied

我在指定的目录中查找了上述临时文件,找不到。所以我不知道如何解决这个问题。

Treepoem 的条形码生成器也有一个 save() 方法,您通常可以在其中保存到文件。我试图保存到一个临时文件,如下所示:

import fitz
import tempfile
import treepoem

treepoem.generate_barcode(
    barcode_type='datamatrixrectangular',
    data='10000010'
).convert('1').save(tempfile.TemporaryFile('barcode_tempfile'))

pdf_file = fitz.open()  # Creating a new file for this example.
pdf_file.new_page()  # Inserting a new blank page.
page = pdf_file[0]

rect = fitz.Rect(70, 155, 200, 230)  # Generic area defined, required to insert barcode into. (x0, y0, x1, y1)

page.insert_image(rect, filename=barcode_tempfile)
pdf_file.save('example_pdf_with_barcode.pdf')

这导致以下错误:

File "<redacted>\example.py", line 8, in <module>
    ).convert('1').save(tempfile.TemporaryFile('barcode_tempfile'))
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<redacted>\AppData\Local\Programs\Python\Python311\Lib\tempfile.py", line 563, in NamedTemporaryFile
    file = _io.open(dir, mode, buffering=buffering,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: invalid mode: 'barcode_tempfile'

所以我不确定我是否可以通过这种方法保存到临时文件。

任何人都可以解释这是否可能,如何最好地解决它?

(目前使用python 3.11)

谢谢,

【问题讨论】:

    标签: python pdf barcode temporary-files


    【解决方案1】:

    您的问题出在临时文件处理方面。我建议坚持使用 Pillow 并专门使用它的设施,而不是深入细节:

    • 像您一样将 PIL 图像转换为 JPEG/PNG,但让 PIL 保存到内存文件
    • 使用 PyMuPDF 插入内存​​映像
    import io  # need this for memory output
    fp = io.BytesIO()  # memory binary file
    treepoem.generate_barcode(
        barcode_type='datamatrixrectangular',
        data='10000010'
    ).convert('1').save(fp, "JPEG"))  # write image to memory
    
    # now insert image into page using PyMuPDF
    # fp.getvalue() delivers the image content in memory
    page.insert_image(rect, stream=fp.getvalue())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-10
      • 1970-01-01
      • 1970-01-01
      • 2011-03-03
      • 2016-08-25
      • 2014-08-11
      • 1970-01-01
      • 2013-03-25
      相关资源
      最近更新 更多