PyPDF2压缩
我在用PyPDF2模块压缩合并后的PDF文件时遇到了一些困难。这是我根据这个链接尝试的代码。
import PyPDF2
path = open('path/to/hello.pdf', 'rb')
path2 = open('path/to/another.pdf', 'rb')
merger = PyPDF2.PdfFileMerger()
merger.append(fileobj=path2)
merger.append(fileobj=path)
pdf.filters.compress(merger)
merger.write(open("test_out2.pdf", 'wb'))
我收到的错误信息是:
TypeError: must be string or read-only buffer, not file
我也尝试在合并完成后再压缩PDF。我是根据使用PDFSAM压缩后得到的文件大小来判断我的压缩失败的。有什么想法吗?谢谢。
4 个回答
0
pypdf
提供了几种方法来减小文件大小:https://pypdf.readthedocs.io/en/latest/user/file-size.html
compress_content_streams
是其中一种方法,它的缺点是可能需要较长时间(这取决于PDF文件的大小;可以把它想象成是PDF版的ZIP压缩):
from pypdf import PdfReader, PdfWriter
reader = PdfReader("example.pdf")
writer = PdfWriter()
for page in reader.pages:
page.compress_content_streams() # This is CPU intensive!
writer.add_page(page)
with open("out.pdf", "wb") as f:
writer.write(f)
0
最开始的方法其实没那么错。只需要在写入文件之前,把页面添加到你的写入器中,并进行压缩就可以了:
...
for i in list(range(reader.numPages)):
page = reader.getPage(i)
writer.addPage(page);
for i in list(range(writer.getNumPages())):
page.compressContentStreams()
...
0
你的错误提示说,必须是字符串或者只读的缓冲区,而不是文件。
所以最好把你的合并结果写成字节或者字符串。
import PyPDF2
from io import BytesIO
tmp = BytesIO()
path = open('path/to/hello.pdf', 'rb')
path2 = open('path/to/another.pdf', 'rb')
merger = PyPDF2.PdfFileMerger()
merger.append(fileobj=path2)
merger.append(fileobj=path)
merger.write(tmp)
PyPDF2.filters.compress(tmp.getvalue())
merger.write(open("test_out2.pdf", 'wb'))
8
PyPDF2这个工具没有一个可靠的压缩方法。不过,它有一个叫做 compress_content_streams()
的功能,描述如下:
这个功能可以通过将所有内容流合并并应用FlateDecode过滤器来压缩页面的大小。
不过,有可能这个功能在某些情况下不会起作用,比如内容流的压缩变成了“自动”的。
总的来说,这在大多数情况下不会有什么改变,但你可以试试这个代码:
from PyPDF2 import PdfReader, PdfWriter
writer = PdfWriter()
for pdf in ["path/to/hello.pdf", "path/to/another.pdf"]:
reader = PdfReader(pdf)
for page in reader.pages:
page.compress_content_streams()
writer.add_page(page)
with open("test_out2.pdf", "wb") as f:
writer.write(f)