web-dev-qa-db-ja.com

PDFをブックマーク付きのPDFTKとマージしますか?

Pdftkを使用して複数のpdfをマージすることはうまく機能しています。ただし、マージされたPDFごとにブックマークを作成する簡単な方法はありますか?

これに関してpdftkのドキュメントには何も表示されていないので、pdftkでは不可能だと思います。

マージされるすべてのファイルは1ページになるので、後でブックマークを追加できるユーティリティが他にあるかどうか疑問に思っていますか?

または、個々のpdfのブックマークを指定しながらマージできる別のLinuxベースのpdfユーティリティ。

33
Jason

複数のPDFをGhostscriptとマージすることもできます。このルートの大きな利点は、ソリューションが簡単にスクリプト化できることであり、実際のプログラミング作業を必要としません。

_gswin32c.exe ^
          -dBATCH -dNOPAUSE ^
          -sDEVICE=pdfwrite ^
          -sOutputFile=merged.pdf ^
          [...more Ghostscript options as needed...] ^
          input1.pdf input2.pdf input3.pdf [....]
_

Ghostscriptを使用すると、pdfmarkステートメントを渡すことができます。このステートメントは、結果のPDFに追加される各ソースファイルの目次とブックマークを追加できます。例えば:

_gswin32c.exe ^
          -dBATCH -dNOPAUSE ^
          -sDEVICE=pdfwrite ^
          -sOutputFile=merged.pdf ^
          [...more Ghostscript options as needed...] ^
          file-with-pdfmarks-to-generate-a-ToC.ps ^
          -f input1.pdf input2.pdf input3.pdf [....]
_

または

_gswin32c.exe ^
          -dBATCH -dNOPAUSE ^
          -sDEVICE=pdfwrite ^
          -sOutputFile=merged.pdf ^
          [...more Ghostscript options as needed...] ^
          file-with-pdfmarks-to-generate-a-ToC.ps ^
          -f input1.pdf ^
             input2.pdf ^ 
             input3.pdf [....]
_

Pdfmarkトピックの概要については、Thomas Merzの PDFmark Primer も参照してください。


編集:
_file-with-pdfmarks-to-generate-a-ToC.ps_の例を挙げたかったのですが、どういうわけか忘れてしまいました。ここにあります:

_[/Page 1 /View [/XYZ null null null] /Title (File 1) /OUT pdfmark
[/Page 2 /View [/XYZ null null null] /Title (File 2) /OUT pdfmark
[/Page 3 /View [/XYZ null null null] /Title (File 3) /OUT pdfmark
[/Page 4 /View [/XYZ null null null] /Title (File 4) /OUT pdfmark 
_

これにより、最初の4ファイルの目次が作成されます==最初の4ページ(材料ファイルがマージされた出力PDFに対してそれぞれ1ページであることを保証するため)。

  1. _[/XYZ null null null]_部分は、リンクをたどったときにページのビューポートとズームレベルが現在のものから変更されないようにします。 (任意の例が必要な場合は、これを行うために_[/XYZ 222 111 2]_と言うことができます。)
  2. /Title (some string you want)thingieはToCにあるテキストを決定します。

また、これらのパラメータをGhostscriptコマンドラインに直接追加することもできます。

_gswin32c.exe ^
       -o merged.pdf ^
       [...more Ghostscript options as needed...] ^
       -c "[/Page 1 /View [/XYZ null null null] /Title (File 1) /OUT pdfmark" ^
       -c "[/Page 2 /View [/XYZ null null null] /Title (File 2) /OUT pdfmark" ^
       -c "[/Page 3 /View [/XYZ null null null] /Title (File 3) /OUT pdfmark" ^
       -c "[/Page 4 /View [/XYZ null null null] /Title (File 4) /OUT pdfmark" ^
       -f input1.pdf ^
          input2.pdf ^ 
          input3.pdf ^ 
          input4.pdf [....]
_



'その他の編集:

ちなみに、Ghostscriptdoesは、2つをマージするために使用するときにブックマークを保持します= PDFファイルを1つに-pdftk.exeはしません。最初の編集のコマンドによって生成されたものを使用しましょう(同じファイルの2つのコピーを効果的に連結します):

_ gswin32c ^
    -sDEVICE=pdfwrite ^
    -o doublemerged.pdf ^
     merged.pdf ^
     merged.pdf
_

ファイル_doublemerged.pdf_には2 * 4 = 8個のブックマークがあります。

  • 予想どおり:ブックマーク1、2、3、および4は、ページ1、2、3、および4にリンクしています。
  • 問題は、ブックマーク5、6、7、8も1、2、3、4ページにリンクしていることです。

その理由は、既存のブックマークが絶対ページ番号によってリンクターゲットに対応していたためです。これを回避するには(そしてブックマークはマージされたファイルで機能します)、名前付きの宛先によってリンクターゲットを指すブックマークを生成する必要があります(そして、これらがマージされるドキュメント全体で一意であることを確認してください)。

(このアプローチはLinuxでも機能します。gswin32cの代わりにgsを使用してください。)


付録

上記のコマンドラインでは、_[...more Ghostscript options as needed...]_をその他のオプションのプレースホルダーとして使用しています。

他のオプションを使用しない場合、Ghostscriptはさまざまなパラメータに組み込みのデフォルトを適用します。しかし、これはあなたの好みに合わないかもしれない結果をあなたに与えるかもしれません。 Ghostscriptは入力に基づいて完全に新しいPDFを生成するため、これは元のオブジェクトの一部が変更される可能性があることを意味します。これは色空間と画像圧縮レベルに当てはまります。

元の埋め込み画像を変更せずにパラメータを適用する方法については、 SuperUser: "Ghostscriptを使用しますが、画像を再処理しないように指示してください" を参照してください。

41
Kurt Pfeifle

すでに述べた他の方法があることは知っていますが、pdftkを使用すると、マージされたpdfを取得し、pdftk関数dump_dataを使用してpdf内の既存の情報の.infoファイルを作成することでブックマークを追加できます。次に、ブックマークごとに次の4行を追加して、ブックマーク情報を.infoファイルに追加できます。

BookmarkBegin
BookmarkTitle: name
BookmarkLevel: level
BookmarkPageNumber: page number

次に、update_info呼び出しを使用して、マージされたpdfブックマークを.infoファイルに書き込んだブックマークで更新します。興味のある人がいれば、autohotkeyでこれを行う簡単な関数をいくつか作成しました。 http://www.autohotkey.com/board/topic/98985-scripts-to-merge-pdfs-and-add-bookmarks-with-pdftk/ を参照してください。

10
steventaitinger

https://stackoverflow.com/a/17781138/547578 でこの回答を参照してください。私はSejdaと呼ばれるものを使用しました。できます。ブックマークを完璧に組み合わせます。 @blablatrosに感謝します。

5
Fish Monitor

使用できるPDFブックマークを追加または編集しすぎます JPdfBookmarks 。これは、私がしばらく使用していて優れた結果が得られた、優れたマルチOSフリーソフトウェアツールです。ただし、ブックマークのみを処理するため、ページをマージまたは並べ替えるには別のツールが必要になります。 pdftkに加えて、PDF Split and Merge(良いアプリですが、UIがおかしい、私の経験からブックマークを台無しにする)、PDF-Shuffler(正常に動作しているように見えますが、一部のファイルの処理中にフリーズすることがあります)、または PdfMod (再配置を処理する場合に最適です、ブックマークのマージと処理。ただし、特定のページにPDFを追加する方法を理解することはできませんでした)。

一部のリンクを提供していないことをお詫びします。初心者として、システムでは2つのハイパーリンクしか追加できません。

4
castaway

@pipitasの良い答えは、ブックマークの問題を完全に解決するものではなく、UNIXのディスカッションに関連する質問があります https://unix.stackexchange.com/questions/17065/add-and-edit-bookmarks- to-pdf/3107 、ここで私は提案します

それでもこれらのUNIXスクリプトを使い続ける場合は、

  1. pdftkからダンプされたブックマークデータを抽出します
  2. ダンプされたブックマークデータをpdfmarks形式に変換する追加のスクリプトを1つ記述します。これは、ghostscriptコマンドgsが受け入れられます。
  3. gsスクリプトを使用して、それらをpdfmarksとマージします

スクリプトはすでに存在します。 PDFをブックマーク付きのPDFTKとマージしますか? からpdf-merge.pyを参照してください。

2
Larry Cai

たぶん、以下が役に立ちます。 1つのディレクトリにあるすべてのpdf(in_nn.pdf)を、入力pdf(in_nn)の名前がToCである1つのout.pdfにマージしたいと思いました。名前を読み取ってページ番号を抽出し、pdfmarksという名前のファイルを生成するpythonスクリプトを作成しました。ファイルのマージは、gsを使用して簡単に実行できます。正確なコマンドはスクリプトによって出力されるため、個別に実行されます(ページサイズの調整またはオペレーティングシステムのために、いくつかの変更が加えられている可能性があります)。

ここにあります。おそらく、Windowsにはいくつかの変更が必要ですか? (英語以外のコメントでごめんなさい)。マージするPDFが配置されているディレクトリでpythonスクリプトを実行するだけです。

#!/usr/bin/env python

import subprocess

# Dieses Skript dient dazu, eine Reihe von pdfs zu einem einzigen pdf zusammenzufassen und bookmarks fuer diese pdf-Datei zu erzeugen.
# Dafuer wird ein Datei pdfmark benoetigt, die mit diesem Skript erzeugt wird.
# Dazu einfach dieses Skript in dem Verzeichnis aufrufen, das genau alle zusammenzufassenden pdfs (*pdf, s.u.) enthaelt.
# Das zusammenfassende pdf wird dann mit diesem Befehl (in der bash) generiert:
# gs -dBATCH -dNOPAUSE -sPAPERSIZE=A4 -sDEVICE=pdfwrite -sOutputFile="all.pdf" $(ls *pdf ) pdfmarks
# Bereits Inhaltsverzeichnisse bleiben erhalten, die neuen kommen ans Ende des Inhaltsverzeichnisses.
#
# pdfmarks sieht dabei prinzipiell so aus:
#
# [/Title (Nr. 1) /Page 1 /OUT pdfmark
# [/Title (Nr. 2) /Page 5 /OUT pdfmark
# [/Title (Nr. 3) /Page 9 /OUT pdfmark
# usw.

p = subprocess.Popen('ls *pdf', Shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

pdfdateien = []
kombinationen = []

for line in p.stdout.readlines():
# p enthaelt alle pdf-Dateinamen
  pdfdateien.append(line)


for datei in pdfdateien:
  cmd = "pdfinfo %s" %datei 
  q=subprocess.Popen(cmd, Shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  kombination = [datei]

for line in p.stdout.readlines():
# p enthaelt alle pdf-Dateinamen
  pdfdateien.append(line)


for datei in pdfdateien:
  cmd = "pdfinfo %s" %datei 
  q=subprocess.Popen(cmd, Shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  kombination = [datei]


  for subline in q.stdout.readlines():
# q enthaelt die Zeilen von pdfinfo
    if "Pages" in subline:
      kombination.append(subline)

  kombinationen.append(kombination)


# Jetzt kombinationen in benoetigtes Format bringen:

kombinationen_bereinigt =  []
out_string1 = "[/Title ("
out_string2 = ") /Page "
out_string3 = " /OUT pdfmark\n"
seitenzahl = 1

for kombination in kombinationen:
  dateiname = kombination[0][0:len(kombination[0])-5]

#
# Hier noch dateiname evtl. verwursten
# z. B.
#  lesezeichen = dateiname[0:1]+" "+dateiname[6:8]+"/"+dateiname[1:5]
  lesezeichen = dateiname

  anz_seiten = kombination[1][16:len(kombination[1])-1]
  seitenzahl_str = str(seitenzahl)

  kombination_bereinigt = out_string1+lesezeichen+out_string2+seitenzahl_str+out_string3
  kombinationen_bereinigt.append(kombination_bereinigt)

  seitenzahl += int(anz_seiten)


# Ausgabe ins file
outfile = open("pdfmarks", "w")

for i in kombinationen_bereinigt:
  outfile.write(i)

outfile.close()

# Merge-Befehl absetzen

print "\nFor merging all pdfs execute this (or similar) command (in bash Shell):"
print "gs -dBATCH -dNOPAUSE -sPAPERSIZE=A4 -sDEVICE=pdfwrite -sOutputFile=\"all.pdf\" $(ls *pdf ) pdfmarks\n"
2
pdfmerger

残念ながら、それを行う簡単な方法はありません。 pdftkが直接構築されているライブラリを使用して、JavaまたはiTextまたはiTextSharpを使用して1ページのポケットベルをマージし、ブックマークを作成する.NETプログラムを作成することができます。 iTextルートに行くと、オンラインまたはiTextブック(iTextの作成者によって書かれた)で利用できる例がたくさんあります。

...または、機能していないものを教えてください。お手伝いできます。

1
khkremer

以下は、pdfmerger( https://stackoverflow.com/a/30524828/3915004 )による回答へのコメントを目的としています。

スクリプトpdfmergerをありがとう!質問がlinuxとマークされていることは知っていますが、Mac OS Xのスクリプトを一般化するには、次の2つのことが必要です。

  • ghostscript gsおよび
  • コマンドpdfinfo(これは、たとえばpopplerに含まれています)

最初にbrew(google it、curl/Ruby-magicコマンド^^を介してインストールされます)を取得してから、次のようにインストールします。

brew install ghostscript
brew install poppler

アドオン:章のタイトルが付いたテキストファイルを読む:

スクリプトを拡張します。私はこのワークフローを主に、編集者のWebサイトからチャプターダウンロードとして入手できる本に使用します。章名を含むテキストファイルは簡単に生成できます。コードへの次のアドオンは、マージするpdfごとに1行を含むテキストファイル「chapters.txt」を追加で読み取ります。 (PDFの数に対応する行数のチェックは実装していません。)

次の行を置き換えるだけで、スクリプトを展開できます。

p = subprocess.Popen('ls *pdf', Shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
c = subprocess.Popen('less chapters.txt', Shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

pdfdateien = []
kombinationen = []
chapternames = []

for line in c.stdout.readlines():
# c contains all chapter-titles
  chapternames.append(line)

for line in p.stdout.readlines():

そして

for index, kombination in enumerate(kombinationen):
#  dateiname = kombination[0][0:len(kombination[0])-5]
#
# Hier noch dateiname evtl. verwursten
# z. B.
#  lesezeichen = dateiname[0:1]+" "+dateiname[6:8]+"/"+dateiname[1:5]
#  lesezeichen = dateiname
  lesezeichen=chapternames[index][:-1]

  anz_seiten = kombination[1][16:len(kombination[1])-1]
0
fabern

Sejda PDF回答の1つ で提案されました)はオンラインサービスとしても利用できます: https ://www.sejda.com/merge-pdf

これは、追加のソフトウェアをインストールせず、ブラウザーからオンラインで作業することを好む場合に役立つことがあります。

マージする手順:

  1. すべてのPDFファイルをWebページにドラッグアンドドロップします
  2. デフォルトでは既存のブックマークはすべて保持され、マージされたドキュメントでも機能します。

  3. オプションで、マージツールは結合されているPDFドキュメントに基づいて目次を作成できます

Option selected to generated Table of contents for merged PDF documents based on filenames

Merged PDF table of contents

マージするオンラインサービスPDFファイルは、1時間あたり最大30ファイル、最大50Mb/200ページのファイルを無料で使用できます。

免責事項:私はSejdaに取り組んでいるオープンソース開発者です。

0
Edi

PdfMod があります。グラフィカルインターフェイスがあり、ブックマークを手動で追加できます。また、すでにブックマークが付いているPDFを編集すると、正しいページを指すように自動的に更新されます。

0
Caio S.

最近のバージョンのpdftk(少なくともv2.02)は、ブックマークとリンクを正しく処理します。

pdftk file1.pdf file2.pdf cat output merged.pdf
0
rriemann