PDFでページを分割する


67

1つの仮想ページで2ページをスキャンしたスキャン済みPDFファイル(PDFファイルのページ)があります。

解像度は高品質です。問題は、読むときにズームし、左から右にドラッグする必要があることです。
いくつかのコマンド(存在しconvertpdftk通常のページ(本から1ページ= PDFファイルの1ページ)で、このPDFファイルを変換することができ、...)またはスクリプトは?


1
それは最も支持された答えではありませんが、これは本当に驚きました。シンプルで、短く、速く、エレガントです。ここでそれを言及する価値があると思いました、時々私たちは他の答えにスクロールするのが
面倒

レコードの場合、逆の操作(複数のページを結合する)はpdfnuppdfjamスイートのを使用して、コマンドライン(「ファイルに印刷」ではなく)から取得できます。
スキッピールグラングロウ

回答:


46

これは、PyPdfライブラリを使用して、仕事をきちんと行う小さなPythonスクリプトです。というスクリプトun2up(または任意のスクリプト)に保存し、実行可能にし(chmod +x un2up)、フィルターとして実行します(un2up <2up.pdf >1up.pdf)。

#!/usr/bin/env python
import copy, sys
from pyPdf import PdfFileWriter, PdfFileReader
input = PdfFileReader(sys.stdin)
output = PdfFileWriter()
for p in [input.getPage(i) for i in range(0,input.getNumPages())]:
    q = copy.copy(p)
    (w, h) = p.mediaBox.upperRight
    p.mediaBox.upperRight = (w/2, h)
    q.mediaBox.upperLeft = (w/2, h)
    output.addPage(p)
    output.addPage(q)
output.write(sys.stdout)

非推奨の警告は無視してください。PyPdfメンテナーのみがそれらに関係する必要があります。

入力が異常な方向を向いている場合、ページを切り捨てるときに異なる座標を使用する必要がある場合があります。参照してください私のコードが正しくスキャンしたPDF内のすべてのページを分割しないのはなぜ?


便利な場合に備えて、2つのツールといくつかの手動介入の組み合わせを使用する以前の回答を次に示します。

  • Pdfjam(少なくともバージョン2.0)、pdfpages LaTeXパッケージに基づいて、ページをトリミングします。
  • Pdftk、左半分と右半分を元に戻します。

pdfpagesが1つのストリームの同じページに2つの異なる変換を適用することができない限り、両方のツールが必要です。の呼び出しでpdftk、42を入力ドキュメントのページ数に置き換えます(2up.pdf)。

pdfjam -o odd.pdf --trim '0cm 0cm 14.85cm 0cm' --scale 1.141 2up.pdf
pdfjam -o even.pdf --trim '14.85cm 0cm 0cm 0cm' --scale 1.141 2up.pdf
pdftk O=odd.pdf E=even.pdf cat $(i=1; while [ $i -le 42 ]; do echo O$i E$i; i=$(($i+1)); done) output all.pdf

pdfjam 2.0をお持ちでない場合は、pdfpagesパッケージでPDFLaTeXをインストールするだけで十分です(Ubuntuではtexlive-latex-recommended が必要でtexlive-latex-recommendedのインストール、おそらく(Ubuntuではtexlive-fonts-recommended texlive-fonts-recommendedをインストールします)、次のドライバーを使用しますファイルdriver.tex

\batchmode
\documentclass{minimal}
\usepackage{pdfpages}
\begin{document}
\includepdfmerge[trim=0cm 0cm 14.85cm 0cm,scale=1.141]{2up.pdf,-}
\includepdfmerge[trim=14.85cm 0cm 0cm 0cm,scale=1.141]{2up.pdf,-}
\end{document}

次に、次のコマンドを実行して、42を入力ファイル内のページ数(これを呼び出す必要があります2up.pdf)に置き換えます。

pdflatex driver
pdftk driver.pdf cat $(i=1; pages=42; while [ $i -le $pages ]; do echo $i $(($pages+$i)); i=$(($i+1)); done) output 1up.pdf

PyPdfライブラリは完璧に機能します。少し変更して、python conv_pdf.py res.pdfで実行しました。コマンドラインからスクリプトシェバンをどのように実行しますか?
xralf

(わずかなスケーリングのため)pdfjamを使用したバージョンも試したいのですが、pdfjamパッケージのインストール後、私のシェルはpdfjamコマンドを認識しません。
xralf

@xralf:私のpythonスクリプトは標準入力から読み取り、標準出力に書き込むだけです。pdfjamバージョンにはpdfjam 2.0が必要です。これはpdfpagesの小さなラッパーに過ぎず、生成するLaTeXを少し追加したので、それを直接使用できます。スケーリングの問題はおそらくpypdfで解決できます。ページサイズの問題である可能性があります(何が起こっているのか、特に関連するページサイズの詳細を教えてくれると助けられるかもしれません)。
ジル「SO-悪であるのをやめる」

ありがとう、違いはほんの少し悪い解像度ですが、これは問題ではありません。ラテックスについてもっと知ったとき、私はそれに戻ります(今は私にとって複雑すぎます、そして解決策はPyPdfで本当に良いです)。
xralf

1
@Gilles Versyの便利なスクリプト。私はpdfjam、pdftkでそのようなものを見ることを期待していました。とにかく、一部の人々は、他の軸でページを分割し、異なる順序を使用するためにいくつかの修正が必要な場合があります。これは、いくつかの行を変更し、使用することで可能になりますq.mediaBox.lowerRight = (w, h/2)
12

52

pythonスクリプト(および他のいくつかのソリューション)で問題が発生したため、追加しただけmutoolでした。これは、エレガントなmupdfリーダーに付属するシンプルで小さな追加です。だからあなたは試すことができます:

mutool poster -y 2 input.pdf output.pdf

水平分割の場合は、交換してくださいyx。もちろん、この2つを組み合わせてより複雑なソリューションにすることもできます。

これを見つけて本当にうれしいです。

mutoolバージョン1.4以降のmupdfが付属していますhttp ://www.mupdf.com/news


インストールmupdfおよびmutoolソースから:

wget http://www.mupdf.com/downloads/mupdf-1.8-source.tar.gz
tar -xvf mupdf-1.8-source.tar.gz
cd mupdf-1.8-source
sudo make prefix=/usr/local install

または、ダウンロードページにアクセスして、新しいバージョンを見つけます。


3
私はdjvuを持っていました...それをポストスクリプト(非常に高速)に変換し、次にpdf(タートルスロー)に変換しました。
ジュリアンピュイド

2
はい、スピードにも本当に満足しています。
マーツ

3
これは最も簡単で優れています。mutoolこのために作られました。また、用心し-yなさい、私はあなたがほしいと思うほとんどの場合と思う-x
フィアットヤフ

2
このユーティリティは非常に高速ですが、ページの順序に問題があります。このコマンドは、最初の位置に右ページを割り当て、2番目の位置に左ページを割り当てます。誰かがこの問題で私を助けることができますか?
ガルシパレデス


16

Imagemagickはそれを1ステップで実行できます。

$ convert in.pdf -crop 50%x0 +repage out.pdf

1
ありがとう。-density 400パラメータを追加すると、品質がさらに向上します。
xralf

11
convertは中間形式としてラスターを使用しているようです。これにより、元のPDFにベクターオブジェクトが含まれている場合でも、ぼやけた外観になります。
12

誰もが途中でページのコンテンツをラスタライズせずにこれを行う方法を知っていますか?または少なくともより高い解像度を設定するために?
トミスラフナキクアルファレビッチ

このレンダリングされたテキストを画像に変換し、画像からPDFを作成しました。写真にはいいかもしれませんが、テキスト抽出には役に立たないかもしれません。
-andrej

6

ImageMagickのConvertコマンドは、ファイルを2つの部分にトリミングするのに役立ちます。http://www.imagemagick.org/Usage/crop/を参照してください

私があなただったら、次のような(シェル)スクリプトを書きます。

  1. pdfsamでファイルを分割します:1ページ=ディスク上の1ファイル(形式は関係ありません。ImageMagickが知っているものを選択してください。PSまたはPDFを使用します。
  2. 各ページについて、前半を切り取り、$ {PageNumber} Aという名前のファイルに配置します

  3. 後半を切り取り、$ {PageNumber} Bという名前のファイルに配置します。

    1A.pdf、1B.pdf、2A.pdf、2B.pdfなどが得られます。

  4. 次に、これをもう一度新しいPDFに組み立てます。 これを行うには多くの方法があります。

1
ImageMagickを使用してファイルをラスタライズしませんか?そして、特に聴衆の非フランス語圏の利益のために、その最後の部分をインラインで説明する必要があります。
ジル 'SO-悪であるのをやめる'

フランス語を理解する必要がないからです。ImageMagickのconvert、pdftk、またはghostscript(gs)を単独で使用してこの目標を達成する方法を示しています。pdftkを使用するのが好きです。「ラスタライズ」はスキャンされたドキュメントなので問題ではありません。
-tiktak

6

以下からの回答に基づいて、ジルどのようにPDFのページ数を見つけるために私が書いたの

#!/bin/bash

pdforiginal=$1
pdfood=$pdforiginal.odd.pdf
pdfeven=$pdforiginal.even.pdf
pdfout=output_$1
margin=${2:-0}
scale=${3:-1}

pages=$(pdftk $pdforiginal dump_data | grep NumberOfPages | awk '{print $2}')

pagesize=$(pdfinfo $pdforiginal | grep "Page size" | awk '{print $5}')
margin=$(echo $pagesize/2-$margin | bc -l)

pdfjam -o $pdfood --trim "0cm 0cm ${margin}pt 0cm" --scale $scale $pdforiginal
pdfjam -o $pdfeven --trim "${margin}pt 0cm 0cm 0cm" --scale $scale  $pdforiginal

pdftk O=$pdfood E=$pdfeven cat $(i=1; while [ $i -le $pages ]; do echo O$i E$i; i=$(($i+1)); done) output $pdfout

rm $pdfood $pdfeven

だから私は走ることができます

./split.sh my.pdf 50 1.2

50は調整マージン、1.2はスケールです。


4

これは、Gillesが投稿したPyPDFコードのバリエーションです。この機能は、ページの向きに関係なく機能します。

import copy
import math
import pyPdf

def split_pages(src, dst):
    src_f = file(src, 'r+b')
    dst_f = file(dst, 'w+b')

    input = pyPdf.PdfFileReader(src_f)
    output = pyPdf.PdfFileWriter()

    for i in range(input.getNumPages()):
        p = input.getPage(i)
        q = copy.copy(p)
        q.mediaBox = copy.copy(p.mediaBox)

        x1, x2 = p.mediaBox.lowerLeft
        x3, x4 = p.mediaBox.upperRight

        x1, x2 = math.floor(x1), math.floor(x2)
        x3, x4 = math.floor(x3), math.floor(x4)
        x5, x6 = math.floor(x3/2), math.floor(x4/2)

        if x3 > x4:
            # horizontal
            p.mediaBox.upperRight = (x5, x4)
            p.mediaBox.lowerLeft = (x1, x2)

            q.mediaBox.upperRight = (x3, x4)
            q.mediaBox.lowerLeft = (x5, x2)
        else:
            # vertical
            p.mediaBox.upperRight = (x3, x4)
            p.mediaBox.lowerLeft = (x1, x6)

            q.mediaBox.upperRight = (x3, x6)
            q.mediaBox.lowerLeft = (x1, x2)

        output.addPage(p)
        output.addPage(q)

    output.write(dst_f)
    src_f.close()
    dst_f.close()

2

最善の解決策は、上記のmutoolでした。

sudo apt install mupdf-tools pdftk

分割:

mutool poster -y 2 input.pdf output.pdf

ただし、ページを左に回転させる必要があります。

pdftk output.pdf cat 1-endleft output rotated.pdf

まだ重複していません...
MUYベルギー

1

基づいて、ベンジャミンによって答え AskUbuntuで、私はと呼ばれるGUIツールで使用することをお勧めしますgscan2pdfを

  1. PDFスキャンファイルをgscan2pdfにインポートします。非画像PDFファイルは機能しない場合があります。スキャンは問題ないので、心配する必要はありません。

    ここに画像の説明を入力してください

  2. ドキュメントのサイズによっては時間がかかる場合があります。読み込まれるまで待ちます。

  3. Ctrl + Aを押してすべてのページを選択し、必要に応じてページを回転(Ctrl + Shift + C)します。

    ここに画像の説明を入力してください

  4. [ツール] >> [クリーンアップ]に移動しますダブルとしてレイアウトを選択し、#output pages = 2を選択します。

    ここに画像の説明を入力してください

  5. [ OK]をクリックして、ジョブが完了するまで待ちます。

    ここに画像の説明を入力してください

  6. PDFファイルを保存します。できた


膨大な数の画像を含む複雑なPDFドキュメントでテストされ、失敗しました。
MUYベルギー

0

Moraes ソリューションが機能しませんでした。主な問題は、x5およびx6の計算でした。ここで、オフセットを考慮する必要があります。つまり、lowerLeftが(0,0)でない場合

そこで、PyPDF2とpython 3を使用するための追加の適応を備えた別のバリエーションがあります。

import copy
import math
import PyPDF2
import sys
import io 

def split_pages(src, dst):
    src_f = io.open(src, 'r+b')
    dst_f = io.open(dst, 'w+b')

    input = PyPDF2.PdfFileReader(src_f)
    output = PyPDF2.PdfFileWriter()

    for i in range(input.getNumPages()):
        p = input.getPage(i) 
        q = copy.copy(p)
        q.mediaBox = copy.copy(p.mediaBox)

        x1, x2 = p.cropBox.lowerLeft
        x3, x4 = p.cropBox.upperRight        

        x1, x2 = math.floor(x1), math.floor(x2)
        x3, x4 = math.floor(x3), math.floor(x4)

        x5 = math.floor((x3-x1) / 2 + x1)
        x6 = math.floor((x4-x2) / 2 + x2)

        if x3 > x4:        
            # horizontal
            p.mediaBox.upperRight = (x5, x4)
            p.mediaBox.lowerLeft = (x1, x2)

            q.mediaBox.upperRight = (x3, x4)
            q.mediaBox.lowerLeft = (x5, x2)
        else:
            # vertical        
            p.mediaBox.lowerLeft = (x1, x6)
            p.mediaBox.upperRight = (x3, x4)

            q.mediaBox.upperRight = (x3, x6)
            q.mediaBox.lowerLeft = (x1, x2)

        output.addPage(p)
        output.addPage(q)

    output.write(dst_f)
    src_f.close()
    dst_f.close()

if __name__ == "__main__":
    if ( len(sys.argv) != 3 ):
        print ('Usage: python3 double2single.py input.pdf output.pdf')
        sys.exit(1)

    split_pages(sys.argv[1], sys.argv[2])
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.