我正在参考 2008 规范使用 Python 解码 PDF 文件: https://web.archive.org/web/20081203002256/https://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf 特别是第 7.4.4.4.
节图像通常以字节流的形式嵌入 PDF 中,每个流都与一个包含该流信息的字典相关联。例如,流通常是原始数据的压缩形式;这些细节由字典中的
Filter
条目描述。
当我得到一个过滤器为
FlateDecode
的流时,这意味着数据是使用 deflate 进行压缩的,并且可以使用 zlib.decompress
轻松反转。但是......为了提高压缩率,原始数据可以通过过滤器进行预处理,例如区分相邻字节 - 当数据有很多相似的值时,结果会压缩得更好。预处理由字典中的 Predictor
条目标识。
Predictor
值15表示使用PNG差分算法;不幸的是,2008 年的 PDF 文档基本上说“PNG 预测(关于编码,PNG 最佳)”。耶。
有人可以向我解释一下(a)这到底意味着哪种 PNG 过滤算法(参考其规范)和(b)理想情况下向我指出一个可以反转它的库。如果缺少后者,我就必须用纯 Python 来反转它,这会很慢。对于我最初的用例来说,速度慢得可以接受,而且我想如果我的需求变得更频繁,我可以(很久)以后将其编写为 C 扩展。
我现在所在的位置是:
bytes
对象,这是原始像素数据Predictor
值,在我当前的示例文档中为 15 目前我的
image
属性方法如下所示:
@property
def image(self):
im = self._image
if im is None:
decoded_bs = self.decoded_payload
print(".image: context_dict:")
print(decoded_bs[:10])
pprint(self.context_dict)
decode_params = self.context_dict.get(b'DecodeParms', {})
color_transform = decode_params.get(b'ColorTransform', 0)
color_space = self.context_dict[b'ColorSpace']
bits_per_component = decode_params.get(b'BitsPerComponent')
if not bits_per_component:
bits_per_component = {b'DeviceRGB': 8, b'DeviceGray': 8}[color_space]
colors = decode_params.get(b'Colors')
if not colors:
colors = {b'DeviceRGB': 3, b'DeviceGray': 1}[color_space]
mode_index = (color_space, bits_per_component, colors, color_transform)
width = self.context_dict[b'Width']
height = self.context_dict[b'Height']
print("mode_index =", mode_index)
PIL_mode = {
(b'DeviceGray', 1, 1, 0): 'L',
(b'DeviceGray', 8, 1, 0): 'L',
(b'DeviceRGB', 8, 3, 0): 'RGB',
}[mode_index]
print(
"Image.frombytes(%r,(%d,%d),%r)...", PIL_mode, width, height,
decoded_bs[:32]
)
im = Image.frombytes(PIL_mode, (width, height), decoded_bs)
im.show()
exit(1)
self._image = im
return im
这向我显示了“前卫”和倾斜的图像,因为我将差异数据解码为颜色数据,并将行标签解码为像素数据,稍微倾斜了后续行。
如果“预测器”参数为 10 或更大,则每行使用的预测器由 每行中的第一个字节给出。在这种情况下,该参数的值没有进一步的意义。 15 并不重要,除了 15 >= 10 之外。