web-dev-qa-db-ja.com

コマンドラインツールを使用してPDF内のすべての画像をバッチ処理するにはどうすればよいですか?

PDFからすべての/ Subtype/Imageラスターイメージオブジェクトを抽出し、別のサードパーティツールを使用してそれらを処理し、元のPDFに再挿入できるLinux用のコマンドラインツールはありますか?

Debianパッケージpoppler-utilsは、PDFからすべての画像を抽出できるツールpdfimagesを提供しますが、それらをPDF =変更した後。

以前にPDFの簡単なパーサーを書いたので、この問題に対する私の現在の見解は

  1. PDFでpdfclean(mupdfパッケージから)を実行して、すべてのストリームを解凍し、解析を容易にします
  2. 単純なパーサーでPDFを解析します(確かにこれはほとんどのPDFを解析できませんが、私のPDF私は幸せです)名前にオブジェクトIDが含まれるビットマップとしてすべての画像を抽出します
  3. サードパーティのプログラムを使用して画像にいくつかのfooを実行します
  4. 元のPDFを再度解析しますが、今回は内部の画像を変更された画像に置き換え、必要に応じて/ Lengthと/ Filterを調整します
  5. pdfcleanを再度実行して、外部参照テーブルのすべてのオフセットを修正します

しかし、おそらくこれをすべて可能にし、私が書いた単純なパーサーの機能に限定されないツールはすでに存在しますか?

そのようなツールが存在しないと言うなら、画像を抽出して後で置き換えることができるライブラリを教えても大丈夫です。

5
josch

これは(まだ)コマンドラインで実行できないようですが、 pdfrw python)を使用して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の品質で再エンコードします。

5
josch

コマンドラインで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に置き換えることができます。

よろしく

5
trax