5

Существует ли инструмент командной строки для Linux, который позволяет мне извлекать все объекты растрового изображения / подтипа / изображения из PDF-файла, позволяет обрабатывать их с помощью другого стороннего инструмента, а затем может повторно вставлять их в исходный PDF-файл?

Пакет poppler-utils Debian содержит инструмент pdfimages, который позволяет мне извлечь все изображения из PDF, но я не могу легко вставить их в PDF после того, как я их изменил.

Я уже писал простые парсеры для PDF, так что мой текущий взгляд на эту проблему будет

  1. запустите pdfclean (из пакета mupdf) в PDF, чтобы распаковать все потоки и тем самым упростить анализ
  2. проанализировать PDF с помощью простого парсера (конечно, он не сможет анализировать большинство PDF, но пока он работает для моего PDF, я счастлив) и извлечь все изображения в виде растровых изображений с идентификатором объекта в их имени
  3. поищите изображения с помощью сторонней программы
  4. снова проанализируйте исходный pdf, но на этот раз замените изображения внутри измененными, адаптируя /Length и /Filter по мере необходимости
  5. снова запустите pdfclean, чтобы исправить все смещения в таблице внешних ссылок

Но может быть, инструмент, который позволяет все это и не ограничивается возможностями простого парсера, написанного мной, уже существует?

Если вы говорите, что такого инструмента не существует, то можно также сообщить мне библиотеку, которая позволяет извлекать и позже заменять изображения.

2 ответа2

5

Кажется, что это (пока) невозможно сделать в командной строке, но я нашел простой способ написания сценариев на python с использованием модуля pdfrw python :

#!/usr/bin/env python
import sys
import os
import zlib
import Image
import StringIO

from pdfrw import PdfReader, PdfDict, PdfArray, PdfName, PdfWriter

def process_image(image):
    if image["/Filter"] == PdfName("FlateDecode"):
        pass
    elif image["/Filter"] == PdfName("DCTDecode"):
        im = Image.open(StringIO.StringIO(image.stream))
        outf = StringIO.StringIO()
        im.save(outf, "JPEG", quality=45)
        image.stream = outf.getvalue()
        outf.close()

def find_images(obj, visited=set()):
    if not isinstance(obj, (PdfDict, PdfArray)):
        return
    myid = id(obj)
    if myid in visited:
        return
    visited.add(myid)

    if isinstance(obj, PdfDict):
        if obj.Type == PdfName.XObject and obj.Subtype == PdfName.Image:
            process_image(obj)
        obj = obj.itervalues()

    for item in obj:
        find_images(item, visited)

if __name__ == '__main__':
    inpfn,outfn = sys.argv[1:]
    reader = PdfReader(inpfn)
    find_images(reader)
    PdfWriter().addpages(reader.pages).write(outfn)

Вы можете потенциально реализовать все, что вы хотите, в функции process_images и даже такие сложные вещи, как вызов внешних программ для изменения текущего изображения, могут быть легко выполнены. В этом примере мы просто используем PIL для перекодирования изображений JPEG с качеством 45.

4

вы можете попробовать использовать inkscape в командной строке

inkscape -S # show all the object inside  the document
inkscape --select=YouImage --verb=YourTransformation 
inkscape --verb-list #to obtain all the possibilities

Или вы можете извлекать изображения, изменять их по своему усмотрению (imagemagick?) затем замените их в своем документе на inkscape.

С уважением

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .