Cắt các trang PDF thành nhiều trang [đã đóng]


16

Tôi đã có một loạt các tệp PDF có chứa hai trang "thực" cho một trang PDF; Tôi muốn cắt đôi chúng thành một nửa và đặt mỗi nửa trên một trang riêng. Về cơ bản, tôi cần một cái gì đó trái ngược hoàn toàn với pdfnup(hoặc psnup). Làm thế nào có thể đạt được kỳ tích này?

Nền tảng là Linux, ưu tiên nguồn mở; vì tôi đã có một đống lớn những thứ này để làm một cái gì đó có thể được viết thành kịch bản (trái ngược với GUI) sẽ rất tuyệt, vì vậy tôi có thể chỉ cho nó một danh sách về chúng và nhai nó đi.

Một tập lệnh có sẵn không phải là lựa chọn duy nhất; nếu có mã mẫu để thao tác các tệp PDF theo cách tương tự với thư viện của bên thứ ba, tôi có thể có thể hack nó để làm những gì tôi muốn.


Câu trả lời:


22

Bạn có thể giải quyết điều này với sự trợ giúp của Ghostscript. pdftkmột mình không thể làm điều đó (theo sự hiểu biết tốt nhất của tôi). Tôi sẽ cung cấp cho bạn các bước dòng lệnh để làm điều này bằng tay. Sẽ dễ dàng để kịch bản này như một thủ tục, cũng với các tham số khác nhau cho kích thước trang và số trang. Nhưng bạn nói rằng bạn có thể tự làm điều đó ;-)

Cách giải quyết vấn đề này với sự trợ giúp của Ghostscript ...

... Và để giải trí, gần đây tôi đã thực hiện nó không phải bằng một tệp đầu vào có các trang "nhân đôi", mà là một trang có "treble-up". Bạn có thể đọc câu trả lời cho trường hợp này ở đây .

Trường hợp của bạn thậm chí còn đơn giản hơn. Bạn dường như có một cái gì đó tương tự như thế này:

+------------+------------+   ^
|            |            |   |
|      1     |      2     |   |
|            |            | 595 pt
|            |            |   |
|            |            |   |
|            |            |   |
+------------+------------+   v
             ^
            fold
             v
+------------+------------+   ^
|            |            |   |
|      3     |      4     |   |
|            |            | 595 pt
|            |            |   |
|            |            |   |
|            |            |   |
+------------+------------+   v
<---------- 842 pt -------->

Bạn muốn tạo 1 PDF với 4 trang, mỗi trang có kích thước 421 pt x 595 pt.

Bước đầu tiên

Trước tiên, hãy trích xuất các phần bên trái từ mỗi trang đầu vào:

gs \
    -o left-sections.pdf \
    -sDEVICE=pdfwrite \
    -g4210x5950 \
    -c "<</PageOffset [0 0]>> setpagedevice" \
    -f double-page-input.pdf

Những thông số này đã làm gì?

Đầu tiên, hãy biết rằng trong PDF 1 inch == 72 điểm . Sau đó, phần còn lại là:

  • -o ...............:Tên tập tin đầu ra. Ngẫu nhiên cũng sử dụng -dBATCH -dNOPAUSE -dSAFER.
  • -sDEVICE=pdfwrite : chúng tôi muốn PDF là định dạng đầu ra.
  • -g................:đặt kích thước phương tiện đầu ra bằng pixel. độ phân giải mặc định của pdfwrite là 720 dpi. Do đó nhân với 10 để có một trận đấu cho PagePackset.
  • -c "..............:yêu cầu Ghostscript xử lý đoạn mã PostScript đã cho ngay trước tệp đầu vào chính (cần phải tuân theo -f).
  • <</PageOffset ....:thiết lập sự dịch chuyển của hình ảnh trang trên phương tiện. (Tất nhiên, đối với các trang bên trái, sự thay đổi [0 0]không có tác dụng thực sự.)
  • -f ...............: xử lý tập tin đầu vào này.

Kết quả nào đã thực hiện lệnh cuối cùng?

Cái này:

Output file: left-sections.pdf, page 1
+------------+  ^
|            |  |
|     1      |  |
|            |595 pt
|            |  |
|            |  |
|            |  |
+------------+  v

Output file: left-sections.pdf, page 2
+------------+  ^
|            |  |
|     3      |  |
|            |595 pt
|            |  |
|            |  |
|            |  |
+------------+  v
<-- 421 pt -->

Bước thứ hai

Tiếp theo, các phần bên phải:

gs \
    -o right-sections.pdf \
    -sDEVICE=pdfwrite \
    -g4210x5950 \
    -c "<</PageOffset [-421 0]>> setpagedevice" \
    -f double-page-input.pdf

Lưu ý bù trừ âm vì chúng tôi đang dịch trang sang trái trong khi giữ cho khu vực xem đứng yên.

Kết quả:

Output file: right-sections.pdf, page 1
+------------+  ^
|            |  |
|     2      |  |
|            |595 pt
|            |  |
|            |  |
|            |  |
+------------+  v

Output file: right-sections.pdf, page 2
+------------+  ^
|            |  |
|     4      |  |
|            |595 pt
|            |  |
|            |  |
|            |  |
+------------+  v
<-- 421 pt -->

Bước cuối cùng

Bây giờ chúng tôi kết hợp các trang thành một tập tin. Chúng tôi cũng có thể làm điều đó với ghostscript, nhưng pdftkthay vào đó chúng tôi sẽ sử dụng vì công việc này nhanh hơn:

pdftk \
  A=right-sections.pdf \
  B=left-sections.pdf \
  shuffle \
  output single-pages-output.pdf
  verbose

Làm xong. Đây là kết quả mong muốn. 4 trang khác nhau, kích thước 421x595 pt.

Kết quả:

+------------+ +------------+ +------------+ +------------+   ^
|            | |            | |            | |            |   |
|     1      | |     2      | |     3      | |     4      |   |
|            | |            | |            | |            |5595 pt
|            | |            | |            | |            |   |
|            | |            | |            | |            |   |
|            | |            | |            | |            |   |
+------------+ +------------+ +------------+ +------------+   v
<-- 421 pt --> <-- 421 pt --> <-- 421 pt --> <-- 421 pt -->

@Un Unknown: Cảm ơn bạn đã bỏ qua! Bạn có thể quan tâm để viết một bình luận chỉ ra một số lý do cho việc này?
Kurt Pfeifle

+1 để sử dụng tuyệt vời nghệ thuật ASCII và hướng dẫn rất rõ ràng. Chỉ cần tôi là CLI n00b, họ sẽ thoát các dòng để dễ đọc hơn, phải không?
Journeyman Geek

@mullhausen: cảm ơn vì đã sửa lỗi chính tả ( 421-> -421). ;-)
Kurt Pfeifle

6

Có một công cụ pdfposter có thể được sử dụng để tạo tệp PDF với nhiều trang cho một trang đầu vào (ốp lát hoặc cắt các trang). Nó tương tự như công cụ poster, hoạt động tương tự đối với các tệp PostScript.


pdfposter không xử lý in nội dung chồng chéo ở các cạnh, để lắp ráp poster dễ dàng hơn. Tuy nhiên, đây là tập lệnh Perl, do đó khá dễ dàng để thêm.
Matthias Urlichs

3

Vì vậy, sau khi tìm kiếm nhiều hơn (có vẻ như "các trang cắt PDF" là một tìm kiếm tốt hơn nhiều), tôi đã tìm thấy một tập lệnh nhỏ gọi là unpnupsử dụng poster, chuyển đổi PDF / PS và pdftkđể làm chính xác những gì tôi cần. Đó là một chặng đường dài, nhưng nó vượt trội hơn nhiều so với các phương pháp khác mà tôi đã tìm thấy (chẳng hạn như sử dụng hình ảnh) bởi vì nó không raster các trang trước khi nhổ chúng ra.

Chỉ trong trường hợp mobileread biến mất vì một số lý do, cốt lõi của tập lệnh (được cấp phép theo GPLv2 trở lên của Harald Hackenberg <hackenberggmx.at>) như sau:

pdftk "$1" burst
for file in pg*.pdf;
do
    pdftops -eps $file
    poster -v -pA4 -mA5 -c0% `basename $file .pdf`.eps > `basename $file .pdf`.tps
    epstopdf `basename $file .pdf`.tps
done
pdftk pg*.pdf cat output ../`basename $1 .pdf`_unpnuped.pdf

1
Phải yêu nó khi mọi người trả lời câu hỏi của riêng họ. Tuy nhiên, nếu bạn cần phải làm điều đó với một giao diện đồ họa, đặc biệt là nếu các kích thước trang là thậm chí không hay bạn muốn trồng thêm mỗi bên, kiểm tra Briss: briss.sourceforge.net
frabjous

Bạn có thể tự làm những gì bạn muốn với PDFTK mà không cần tất cả các chuyển đổi.
CarlF

@CarlF: Tôi nghĩ rằng điều đó là có thể, nhưng tôi không thể thấy bất cứ điều gì trong trang man PDFTK để thao túng nội dung của các trang. Có con trỏ nào cho tôi không?
womble

@frabjous: Có gì sai khi trả lời câu hỏi của riêng bạn?
Kurt Pfeifle

1
@womble: chuyển đổi của bạn đi qua PS / EPS. Điều này chắc chắn sẽ dẫn đến tổn thất về chất lượng (phông chữ nhúng, trong suốt, v.v.). Đề nghị của tôi tránh PDF => EPS => PDFcon đường rủi ro và đi PDF => PDF => PDFcon đường an toàn hơn .
Kurt Pfeifle

2

Tôi thấy câu trả lời của Kurt Pfeifle rất hữu ích cho tình huống tương tự của tôi. Tôi nghĩ rằng tôi có thể chia sẻ sửa đổi giải pháp của mình với người khác ...

Tôi cũng có một bản PDF được quét có 2 trang trên mỗi tờ. Đó là bản quét 11 x 8,5 (inch) của một tập sách khâu yên ngựa được ghim lại khi được quét ban đầu, vì vậy: trang PDF 1 = bìa sau và bìa trước; PDF trang 2 = trang 2 và 3, v.v ... Điều này đọc trên màn hình tốt nhưng bạn không thể in nó và sau đó ghim nó để tạo ra nhiều bản sao của tập sách.

Tôi cần để có thể in cái này trên máy photocopy song công; tức là biến nó TRỞ LẠI thành một tệp PDF "áp đặt", sẵn sàng để in. Vì vậy, bằng cách sử dụng giải pháp của Kurt, tôi đã tạo ra "một lớp lót" này để chuyển nó trở lại thành nửa trang, theo đúng thứ tự trang một lần nữa. Nó sẽ hoạt động cho bất kỳ CHIỀU CAO và WIDTH, và cho bất kỳ số lượng trang. Trong trường hợp của tôi, tôi đã có một cuốn sách nhỏ 40 trang (20 trang được quét trong PDF.)

HEIGHT=8.5 WIDTH=11 ORIG_FILE_PATH="original.pdf" \
count=$(set -xe; \
gs -o left.pdf -sDEVICE=pdfwrite \
-g$(perl -e "print(($WIDTH / 2) * 720)")x$(perl -e "print($HEIGHT * 720)") \
-c "<</PageOffset [0  0]>> setpagedevice" \
-f "$ORIG_FILE_PATH" >/dev/null; \
gs -o right.pdf -sDEVICE=pdfwrite \
-g$(perl -e "print(($WIDTH / 2) * 720)")x$(perl -e "print($HEIGHT * 720)") \
-c "<</PageOffset [-$(perl -e "print(($WIDTH / 2) * 72)")  0]>> setpagedevice" \
-f "$ORIG_FILE_PATH" | grep Page | wc -l ); \
echo '>>>>>' Re-ordering $count pages...; \
(set -xe; pdftk A=right.pdf B=left.pdf cat \
A1 `set +xe; for x in $(seq 2 $count); do echo B$x A$x; done` B1 \
output ordered.pdf); \
echo "Done. See ordered.pdf"

Bạn chỉ cần thay đổi một vài tham số đầu tiên trong lệnh này để chỉ định HEIGHT và WIDTH và ORIG_FILE_PATH. Phần còn lại của lệnh tính toán các kích cỡ khác nhau và gọi gs hai lần, sau đó pdftk. Nó thậm chí sẽ đếm các trang trong quá trình quét của bạn và sau đó tạo ra đặc tả sắp xếp chính xác (cho kịch bản tôi đã đưa ra).

Nó đưa ra một số tiến bộ về những gì nó đang làm, sẽ như thế này:

+++ perl -e 'print((11 / 2) * 720)'
+++ perl -e 'print(8.5 * 720)'
++ gs -o left.pdf -sDEVICE=pdfwrite -g3960x6120 -c '<</PageOffset [0  0]>> setpagedevice' -f original.pdf
++ wc -l
++ grep Page
+++ perl -e 'print((11 / 2) * 720)'
+++ perl -e 'print(8.5 * 720)'
+++ perl -e 'print((11 / 2) * 72)'
++ gs -o right.pdf -sDEVICE=pdfwrite -g3960x6120 -c '<</PageOffset [-396  0]>> setpagedevice' -f original.pdf
>>>>> Re-ordering 20 pages...
++ set +xe
+ pdftk A=right.pdf B=left.pdf cat A1 B2 A2 B3 A3 B4 A4 B5 A5 B6 A6 B7 A7 B8 A8 B9 A9 B10 A10 B11 A11 B12 A12 B13 A13 B14 A14 B15 A15 B16 A16 B17 A17 B18 A18 B19 A19 B20 A20 B1 output ordered.pdf
Done. See ordered.pdf

Tiếp theo, để có được sự áp đặt trang mà bạn cần cho một cuốn sách nhỏ được in, bạn chỉ cần "in" order.pdf trên một kích thước trang tùy chỉnh với kích thước chính xác mà bạn cần (trong ví dụ của tôi, 5,5 x 8,5), gửi nó đến "làm sách nhỏ "Công cụ (trong trường hợp của tôi, tôi đã sử dụng Tạo sách nhỏ cho Mac của Christoph Vogelbusch từ http://doad.cnet.com/Create-Booklet/3000-2088_4-86349.html ).

PDF kết quả bây giờ sẽ trở lại kích thước trang ban đầu là 11 x 8,5 với 2 trang trên mỗi tờ, nhưng thứ tự sẽ sao cho bạn có thể in nó hai mặt, ràng buộc cạnh ngắn và voilà! bạn sẽ có một bản in bạn có thể sao chép và gấp và khâu yên ngựa, sao chép tập sách gốc mà không bao giờ tháo rời (hoặc thậm chí nhất thiết phải nhìn thấy) bản gốc.

Hy vọng điều này sẽ giúp được ai đó!

-c


1

Dựa trên câu trả lời của piptas ở trên:

Trên các cửa sổ, để tách các tệp PDF có kích thước chữ với một ảnh bìa duy nhất khi bắt đầu, phần sau đây rất hữu ích cho tôi (lưu ý việc sử dụng [-612 0] trong bước thứ hai, một giá trị dương tạo ra các trang trống vì nó đã đẩy sai cách .)

gswin32c -o left-sections.pdf -sDEVICE=pdfwrite -dFirstPage=2 -g6120x7920 -c "<</PageOffset [0 0]>> setpagedevice" -f input.pdf

Lưu ý việc sử dụng -dFirstPage=2hướng dẫn gs để bắt đầu xử lý ở trang 2.

gswin32c -o right-sections.pdf -sDEVICE=pdfwrite -dFirstPage=2 -g6120x7920 -c "<</PageOffset [-612 0]>> setpagedevice" -f input.pdf

Điều này tạo ra các phần phải.pdf theo cùng một cách. Và bây giờ ảnh bìa:

gswin32c -o cover.pdf -sDEVICE=pdfwrite -dLastPage=1 -g6120x7920 -c "<</PageOffset [0 0]>> setpagedevice" -f input.pdf

Tiếp theo, vì tôi không muốn hợp nhất với pdftk bằng cách sử dụng trang nhập thủ công, tôi chia các phần bên trái và bên phải thành các tệp PDF riêng biệt trong một thư mục mới.

mkdir input_file
copy cover.pdf input_file\0000.pdf
pdftk left-sections.pdf burst output input_file\%04d_A.pdf
pdftk right-sections.pdf burst output input_file\%04d_B.pdf

Sau đó, tôi tham gia các tệp PDF trong thư mục đó, theo thứ tự bảng chữ cái (và may mắn là điều đó có nghĩa là chúng được sắp xếp theo đúng thứ tự!) Và tôi cũng chạy lại kết quả qua ghostscript để sửa "Cảnh báo: Số thế hệ trong phạm vi 0..65535, giả sử 0. " lỗi được tạo bởi pdftk mà ghostscript gọi là "itext-paulo-155 (itextpdf.sf.net-lawagie.com)" - nó cũng đã xảy ra để giảm một nửa kích thước tệp trong cách sử dụng của tôi. Với bản gốc 4,5 MB, kết quả của pdftk là 6,7 MB và việc tái xử lý của gswin32c đã giảm xuống còn 3,2 MB.

pdftk input_file\*.pdf cat output input_temp.pdf
gswin32c -o final_output.pdf -sDEVICE=pdfwrite -f input_temp.pdf

Và chúng ta đã hoàn thành! Vui lòng xóa thư mục input_file, cover.pdf, input_temp.pdf, right_sections.pdf và left_sections.pdf. ;-)


1

nếu bạn chỉ cần xuất tất cả các pdf bên trái trong một tài liệu và tất cả các pdf bên phải trong một tài liệu, thì tập lệnh sau dựa trên câu trả lời của Kurt Pfeifle sẽ thực hiện thủ thuật (hoạt động ở mọi độ cao và chiều rộng):

$ cat split.sh
#!/bin/bash                                                                     

dims=$(pdfinfo "$1" | grep -i "page size:" | cut -d ":" -f2)                    
width=$(echo "$dims" | cut -d " " -f7)                                          
height=$(echo "$dims" | cut -d " " -f9)                                         
half_width=$(echo "$width * 0.5" | bc -l | cut -d "." -f1)                      
half_widthtt=$(echo "$width * 5" | bc -l | cut -d "." -f1)                      
heighttt=$(echo "$height * 10" | bc -l | cut -d "." -f1)                        

echo "pdf $1 has height $height and width $width"                               

gs -o "left-$1" -sDEVICE=pdfwrite -g"$half_widthtt"x"$heighttt" -c "<</PageOffset [0 0]>> setpagedevice" -f "$1"
gs -o "right-$1" -sDEVICE=pdfwrite -g"$half_widthtt"x"$heighttt" -c "<</PageOffset [-$half_width 0]>> setpagedevice" -f "$1"

sau đó chạy nó như vậy:

$ ./split.sh thepdftosplit.pdf
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.