PDF로 페이지 분할


67

하나의 가상 페이지에서 두 페이지를 스캔 한 스캔 한 pdf 파일이 있습니다 (pdf 파일의 페이지).

해상도가 양호합니다. 문제는 읽을 때 확대하고 왼쪽에서 오른쪽으로 드래그해야한다는 것입니다. 이 pdf 파일을 일반 페이지 (book의 한 페이지 = pdf 파일의 한 페이지)로 변환 할 수
있는 명령 ( convert,, pdftk...) 또는 스크립트가 있습니까?


1
가장 답답한 답변은 아니지만 답변은 정말 놀랐습니다. 간단하고 짧고 빠르며 우아합니다. 다른 답변으로 스크롤하기에는 너무 게으
르기

레코드의 pdfnup경우 pdfjam스위트에서을 사용 하여 명령 행 ( "파일로 인쇄"대신)에서 리버스 조작 (여러 페이지에 결합)을 얻을 수 있습니다 .
Skippy le Grand Gourou

답변:


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의 모든 페이지를 올바르게 분할하지 않는 이유를 참조하십시오 .


유용한 경우를 대비하여 두 가지 도구와 수동 개입의 조합을 사용하는 이전 답변이 있습니다.

  • Pdfjam 에 기초 (적어도 버전 2.0), pdfpages의 LaTeX의 패키지는 페이지를자를 수 있습니다;
  • Pdftk , 왼쪽과 오른쪽 반을 다시 합치십시오.

pdfpages가 한 스트림에서 동일한 페이지에 두 가지 다른 변환을 적용 할 수 없기 때문에 두 도구가 모두 필요합니다. 에 대한 호출에서 pdftk42를 입력 문서의 페이지 수 ( 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를 설치하면 충분합니다 (우분투 : texlive -latex 권장 texlive-latex 권장 설치 및 아마도 (우분투 : texlive-fonts-recommended texlive-fonts 권장 설치 ) 필요). 다음 드라이버를 사용하십시오. 파일 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 : 내 파이썬 스크립트는 표준 입력에서 읽고 표준 출력에 씁니다. pdfjam 버전에는 pdfjam 2.0이 필요합니다. 그것은 pdfpages 주위에 작은 래퍼 일뿐이며 생성하는 LaTeX 비트를 추가하여 직접 사용할 수 있습니다. 스케일링 문제는 아마도 pypdf로 해결할 수 있습니다. 페이지 크기 문제 일 수 있습니다 (발생하는 일, 특히 관련된 페이지 크기에 대한 자세한 내용을 제공하면 도움이 될 수도 있고 그렇지 않을 수도 있습니다).
Gilles

고마워요, 그 차이는 해상도가 약간 나빠지지만 이것은 중요하지 않습니다. Latex에 대해 더 많이 알면 다시 되돌릴 것입니다 (지금은 너무 복잡하고 솔루션은 PyPdf에 정말 좋습니다).
xralf

1
@Gilles Versy 유용한 스크립트. 나는 pdfjam, pdftk에서 그런 것을 볼 것으로 예상했다. 어쨌든 어떤 사람들은 다른 축으로 페이지를 나누고 다른 순서를 사용하기 위해 약간의 수정을 원할 수 있습니다. 이것은 몇 줄을 바꾸고 다음을 사용하여 가능합니다.q.mediaBox.lowerRight = (w, h/2)
ony

52

파이썬 스크립트 (및 다른 여러 솔루션)에 문제가 있었기 때문에 추가 한 것만으로도 mutool훌륭했습니다. 우아한 mupdf리더 와 함께 제공되는 간단하고 작은 추가 기능 입니다. 그래서 당신은 시도 할 수 있습니다 :

mutool poster -y 2 input.pdf output.pdf

수평 분할의 경우, 교체 y와 함께 x. 물론 더 복잡한 솔루션을 위해 두 가지를 결합 할 수도 있습니다.

이것을 발견하게 된 것을 정말로 기쁘게 생각합니다 (수년 간의 mupdf 사용 후 :)

mutool1.4 버전부터 mupdf와 함께 제공됩니다 : http://www.mupdf.com/news


소스 설치 mupdfmutool소스 :

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를 가지고 있었다 ... 나는 그것을 postscript (quite fast)로 바꾸었다가 pdf (turtle slow)로 바꾸었다.
Julien Puydt

2
예, 나는 또한 속도에 정말로 만족했습니다.
martz

3
이것은 가장 쉽고 좋습니다. mutool이것을 위해 만들어졌습니다. 또한 -y대부분의 경우 원하는 것은 -x입니다.
fiatjaf

2
이 유틸리티는 매우 빠르지 만 페이지 순서에 문제가 있습니다. 이 명령은 첫 번째 위치에서 오른쪽 페이지를, 두 번째 위치에서 왼쪽 페이지를 할당합니다. 누군가이 문제를 도와 줄 수 있습니까?
garciparedes


16

Imagemagick은 한 번에 다음 작업을 수행 할 수 있습니다.

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

1
감사. -density 400매개 변수를 추가하면 품질이 훨씬 좋아집니다.
xralf

11
convert는 래스터를 중간 형식으로 사용하는 것 같습니다. 원본 PDF에 벡터 객체가 포함되어 있어도 흐릿하게 보입니다.
ony

누구나 페이지 내용을 래스터 화하지 않고 또는 적어도 더 높은 해상도를 설정하지 않고이를 수행하는 방법을 알고 있습니까?
Tomislav Nakic-Alfirevic

텍스트를 이미지로 렌더링하고 이미지에서 pdf를 만들었습니다. 사진에는 ​​좋지만 텍스트 추출에는 쓸모가 없습니다.
안드레이

6

ImageMagick의 변환 명령을 사용하면 파일을 두 부분으로자를 수 있습니다. http://www.imagemagick.org/Usage/crop/를 참조 하십시오

내가 당신이라면, 나는 다음과 같은 (쉘) 스크립트를 작성할 것입니다 :

  1. 디스크에 pdfsam : 1 page = 1 파일로 파일을 분할하십시오 (포맷은 중요하지 않습니다. ImageMagick이 알고있는 것을 선택하십시오. PS 또는 PDF 만 가져갈 것입니다.
  2. 각 페이지에 대해 전반부를 자르고 $ {PageNumber} A라는 파일에 넣습니다.

  3. 후반을 자르고 $ {PageNumber} B라는 파일에 넣습니다.

    1A.pdf, 1B.pdf, 2A.pdf, 2B.pdf 등을 얻습니다.

  4. 이제 이것을 새로운 PDF로 다시 조립하십시오. 이를 수행하는 방법에는 여러 가지가 있습니다.

1
ImageMagick을 사용하여 파일을 래스터 화하지 않습니까? 그리고 특히 청중이 아닌 비방 문자의 이익을 위해 마지막 부분을 인라인으로 설명해야합니다.
Gilles

프랑스어를 이해할 필요가 없기 때문입니다. 이 목표를 달성하기 위해 ImageMagick의 convert, pdftk 또는 ghostscript (gs) 만 사용하는 방법 만 보여줍니다. 나는 pdftk를 사용하는 것을 좋아한다. "래스터 링"은 스캔 한 문서이므로 중요하지 않습니다.
tiktak

6

Gilles의 답변 과 내가 작성한 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 Belgium

1

에 기초 벤자민 의해 답변을 AskUbuntu에서, 나는라는 GUI 도구를 사용하는 것이 좋습니다 gscan2pdf을 .

  1. PDF 스캔 파일을 gscan2pdf로 가져 옵니다. 이미지가 아닌 PDF 파일은 작동하지 않을 수 있습니다. 스캔은 괜찮으므로 걱정할 필요가 없습니다.

    여기에 이미지 설명을 입력하십시오

  2. 문서 크기에 따라 시간이 걸릴 수 있습니다. 로드 될 때까지 기다리십시오.

  3. 를 눌러 Ctrl + A는 모든 페이지를 선택한 다음합니다 (Ctrl 키 + 시프트 + C) 회전 필요한 경우를.

    여기에 이미지 설명을 입력하십시오

  4. 도구 >> 정리로 이동하십시오 . 레이아웃double# output pages = 2 로 선택하십시오 .

    여기에 이미지 설명을 입력하십시오

  5. 히트 확인 하고, 작업이 완료 될 때까지 기다립니다.

    여기에 이미지 설명을 입력하십시오

  6. PDF 파일을 저장하십시오 . 끝난.


수많은 이미지가 포함 된 복잡한 pdf 문서로 테스트를 통과하지 못했습니다.
MUY Belgium

0

moraes 솔루션 이 작동하지 않았습니다. 주요 문제는 x5와 x6 계산이었습니다. 여기서 lowLeft가 (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.