Как преобразовать 1-страничный PDF-файл в двухстраничный PDF-файл?
Я хотел бы напечатать PDF-файл, чтобы на первой странице были первые две страницы, на задней - третья и четвертая, и так далее.
----------------- -----------------
| | | | | |
| | | | | |
| 1 | 2 | | 3 | 4 | . . .
| | | | | |
|_______|_______| |_______|_______|
page 1 - front page 1 - back
Поскольку мой принтер, использующий Linux, не поддерживает двустороннюю печать вручную, я подумал, что, возможно, я мог бы отредактировать PDF соответствующим образом.
Но как?
12 ответов
В дополнение к тому, что было упомянуто, PDFjam включает в себя инструмент командной строки, pdfnup
который делает это. (Он использует пакет pdfpages для PDFLaTeX, который вы также можете использовать.)
Если вы предпочитаете графический интерфейс, jPDFtweak является еще одним вариантом.
Используйте pdfnup:
$ pdfnup file.pdf
Это создаст новый файл PDF точно так, как вы просили.
Это достаточно старый вопрос, чтобы думать, что имеющиеся у нас варианты в то время отсутствовали, но, возможно, оно заслуживает современного решения.
Программы просмотра PDF в Linux обычно используют параметры / свойства печати, чтобы установить макет страницы, и там можно распечатать несколько страниц на листе / стороне. Идея состоит в том, чтобы использовать их для печати в формате PDF.
Evince может сделать это, также qpdfview. Больше здесь.
qpdfview
выказывать
PDF Studio Viewer
Другие программы просмотра PDF должны иметь аналогичные параметры.
Для тех, кто хочет взять 1 или 2 pg pdf и превратить его в pdf с 2 копиями этого бок о бок в альбомной ориентации (отлично подходит для печати листовок), сделайте:
Превратите ввод в 1 или 2 pg pdf в вывод, содержащий дублированную копию этих страниц (1-pg pdf -> 2-pg pdf, 2-pg pdf -> 4-pg pdf и т. Д.):
pdfunite in.pdf in.pdf out.pdf
Объедините этот файл с дубликатами-копиями в файл формата 2 страницы на сторону в альбомной ориентации, например, для печати листовок:
pdfnup out.pdf
Или все в одной строке:
pdfunite in.pdf in.pdf out.pdf && pdfnup out.pdf
Обратите внимание, что out.pdf
является вкладом в pdfnup
, Полученный выходной файл из pdfnup
будет называться " out-nup.pdf ".
Кроме того, смотрите вывод pdfnup
команда, и вы увидите подробную форму команды, которую она на самом деле выполняет, что дает вам некоторое представление о параметрах, которые вы можете передать в нее. По всей видимости pdfnup
использования pdfjam
под капотом:
pdfjam: эффективный вызов для этого прогона pdfjam:
/usr/bin/pdfjam --suffix nup --nup '2x1' --landscape -- out.pdf -
Пример:
Оригинальный PDF (1 обычный pg в книжной ориентации), " in.pdf ":
Окончательный PDF (2 строчки бок о бок в альбомной ориентации), " out-nup.pdf ":
- теперь можно разрезать пополам по середине, чтобы раздать как листовки
Простая функция Bash: make_flyer
Скопируйте и вставьте эту функцию bash в конец файла "~/.bashrc", чтобы получить доступ к простой и удобной в использовании команде. make flyer
:
# Description: outputs a landscape-oriented flyer pdf ("my/pdf/input--flyer.pdf") for each 1 or more pg input pdf ("my/pdf/input.pdf")
# - 1-pg input PDFs are converted to a 1-sided landscape, printable flyer that you cut down the center to make
# 2 flyers
# - 2-pg input PDFs are converted to a 2-sided landscape, printable flyer (flip on short edge when printing
# double-sided), and also cut down the middle to make 2 flyers
# - **3+ pg input PDFs**: using `pdfnup` directly in this case would make more sense, since this function will
# otherwise unneccessarily create 2 copies
# - 3 and 4-pg input PDFs are converted to a single piece of paper, double-sided, flipped on short edge, x 2 copies.
# No cutting is necessary
# - 5+ pg input PDFs simply require half as much paper to print is all since you get 2 pages per side of paper;
# they do NOT print like booklets, but rather just as a landscape-printed, flipped-on-short-edge bundle of pages
# (like a deck of slides). You get *2 copies* per print though, so just print half the pages.
make_flyer() {
num_args=$# # see: https://stackoverflow.com/questions/4423306/how-do-i-find-the-number-of-arguments-passed-to-a-bash-script/4423321#4423321
suffix="flyer"
loop_cnt=0
for inputpdf in "$@"
do
((loop_cnt++))
echo "==== CONVERTING PDF $loop_cnt OF $num_args ===="
echo " INPUT: \"$inputpdf\""
# Strip off the .pdf extension from the input path, while retaining the rest of the path
# - See: https://stackoverflow.com/questions/12152626/how-can-i-remove-the-extension-of-a-filename-in-a-shell-script/32584935#32584935
input_path_base="$(echo "$inputpdf" | rev | cut -f 2- -d '.' | rev)"
input_file_base="$(basename "$inputpdf" .pdf)"
temp_pdf="${input_path_base}-.pdf" # is "input_path_base-.pdf"
echo " OUTPUT: \"$(pwd)/${input_file_base}--${suffix}.pdf\""
# Convert a single 1-pg pdf into a temporary 2-pg pdf
pdfunite "$inputpdf" "$inputpdf" "$temp_pdf"
# Lay out the temporary 2-pg pdf into a side-by-side 1-sided flyer to print; creates "input_path_base--flyer.pdf"
# Note that `pdfnup` places the output from this operation in the location from where you call this script
# (ie: in your `pwd` [Present Working Directory])!--NOT the location where temp_pdf is located!
pdfnup "$temp_pdf" --suffix $suffix
# Delete the temporary 2-pg pdf, called "input_path_base-.pdf", thereby leaving only the original
# "input_path_base.pdf" and the new "input_path_base--flyer.pdf"
rm "$temp_pdf"
done
}
alias make_flyer_help='echo -e "Ex usage: make_flyer \"path/to/inputpdf.pdf\" - Creates a landscape-side-by-side flyer version called \"inputpdf--flyer.pdf\"\n *in your pwd* from a 1 or 2 pg input pdf called \"path/to/inputpdf.pdf\". Accepts multiple arguments. Ex:\n make_flyer \"path/to/inputpdf1.pdf\" \"path/to/inputpdf2.pdf\""'
Пример использования:
make_flyer "path/to/inputpdf1.pdf" "path/to/inputpdf2.pdf"
См. Справочную информацию:
make_flyer_help
Выход:
$ make_flyer_help Ex usage: make_flyer "path/to/inputpdf.pdf" - Creates a landscape-side-by-side flyer version called "inputpdf--flyer.pdf" *in your pwd* from a 1 or 2 pg input pdf called "path/to/inputpdf.pdf". Accepts multiple arguments. Ex: make_flyer "path/to/inputpdf1.pdf" "path/to/inputpdf2.pdf"
Рекомендации:
- /questions/938052/kak-preobrazovat-1-stranichnyij-pdf-fajl-v-dvuhstranichnyij-pdf-fajl/938069#938069
- https://stackoverflow.com/a/11280219/4561887
Связанный:
Bash Рекомендации:
- Bash Как передать аргументы в функцию bash: https://bash.cyberciti.biz/guide/Pass_arguments_into_a_function
- Конкатенация строк в Bash: https://linuxize.com/post/bash-concatenate-strings/
- Bash выполнить cmd, хранящийся в виде строки! https://stackoverflow.com/questions/2005192/how-to-execute-a-bash-command-stored-as-a-string-with-quotes-and-asterisk
- Перебрать Bash по всем входным данным в cmd: https://stackoverflow.com/questions/255898/how-to-iterate-over-arguments-in-a-bash-script/255913
- Bash передавая параметры в функцию: https://stackoverflow.com/questions/6212219/passing-parameters-to-a-bash-function/6212408
- Как преобразовать 1-pg pdf во флаер [мои собственные ответы!]: Как преобразовать 1-страничный PDF-файл в 2-страничный PDF-файл на листе?
Вы можете сделать это с помощью PyPDF2. Приведенный ниже код не является идеальным решением вашей проблемы, но, надеюсь, он поможет другим, пришедшим сюда из Google.
#!/usr/bin/env python
# requires PyPdf2 library, version 1.26 or above -
# its homepage is https://pythonhosted.org/PyPDF2/index.html
# running: ./this-script-name output.pdf file-with-pdf-list
import copy, sys
from PyPDF2 import PdfFileWriter, PdfFileReader, pdf
output = PdfFileWriter()
output_page_number = 0
alignment = 6 # align on 6 pages for printing 6 up
for filename in sys.argv[2:]:
page = pdf.PageObject.createBlankPage(None, 850, 1100)
input = PdfFileReader(open(filename, "rb"))
position = 0
for i in range(0, input.getNumPages()):
x = 0
# Two Up
# if position == 0:
# position = 1
# page.mergeScaledTranslatedPage(input.getPage(i), 0.5, 100, 650)
#else:
# page.mergeScaledTranslatedPage(input.getPage(i), 0.5, 100, 100)
# output.addPage(page)
# page = pdf.PageObject.createBlankPage(output)
# position = 0
# 6 Up
scale = 0.25
col1 = 100
col2 = 450
sep = 130
row3 = sep + 25
row2 = row3 + sep + 215
row1 = row2 + sep + 215
if position == 0:
position = 1
page.mergeScaledTranslatedPage(input.getPage(i), scale, col1, row1)
elif position == 1:
position = 2
page.mergeScaledTranslatedPage(input.getPage(i), scale, col2, row1)
elif position == 2:
position = 3
page.mergeScaledTranslatedPage(input.getPage(i), scale, col1, row2)
elif position == 3:
position = 4
page.mergeScaledTranslatedPage(input.getPage(i), scale, col2, row2)
elif position == 4:
position = 5
page.mergeScaledTranslatedPage(input.getPage(i), scale, col1, row3)
else:
page.mergeScaledTranslatedPage(input.getPage(i), scale, col2, row3)
output.addPage(page)
page = pdf.PageObject.createBlankPage(output)
position = 0
if position != 0:
output.addPage(page)
output.write(open(sys.argv[1], "wb"))
Очень быстрый и грязный вариант, если у вас есть браузер Google Chrome, - это использовать встроенный PDF-принтер / средство просмотра и функцию "сохранить как PDF".
Откройте / перетащите PDF-файл на вкладку Chrome (если отображается окно сохранения файла, вам необходимо включить опцию внутреннего просмотра PDF-файлов, перейдите на эту страницу в своем браузере http://chrome://settings/content/pdfDocuments)
Щелкните правой кнопкой мыши и выберите "Печать".
На панели печати выберите "Сохранить как PDF".
Выберите количество страниц в "Страницах на листе".
ПРИМЕЧАНИЕ: у него может быть несколько причуд, если страницы не ровные или разное соотношение сторон, а также, насколько я могу судить, формат страницы - A4, и я не могу найти очевидного способа его изменить.
Кроме того, если у вас установлен Adobe Acrobat, вы можете использовать принтер Adobe PDF, в этом случае будут доступны дополнительные и расширенные параметры.
Существуют бесплатные инструменты командной строки с открытым исходным кодом для преобразования PDF-файлов в читательские, буклетные и т. Д.
Я потерял приложение, которое использовал, так что никакой помощи там нет, но из быстрого поиска я вижу программу под названием pdfshuffler ( http://sourceforge.net/projects/pdfshuffler/), которая может быть тем, что вам нужно. Имеет графический интерфейс, поэтому вряд ли будет автоматическим, но это интерфейс для другого инструмента...
Это программное обеспечение, которое я тестировал в операционной системе Solaris 11.2, может создать такую схему, которая называется 2-up, обычно используемая для раздаточного материала в аудиториях или на собраниях. Возможно изготовление других схем; например, раздавать 3 или 4 или более страниц на одном листе или на обеих сторонах листа. Его можно запустить из терминала, так как это JAR-файл, или просто запустить графический интерфейс для облегчения доступа. Помимо Solaris также совместимы другие дистрибутивы Linux, которые запускают программное обеспечение как "исполняемые" с привилегиями суперпользователя. Помните, что не используйте "Открыть архив". Он также работает на любых Windows и Mac, где уже установлена Java Runtime Environment (JRE), как это происходит в большинстве случаев. Программное обеспечение является Dysprosium Imposition и является бесплатным для загрузки и использования.
Если у вас есть возможность распечатать в файл. печатать в файл с двумя страницами на страницу настройки и с нечетными страницами. повторите процесс с четными страницами. Теперь распечатайте нечетные, переверните напечатанные бумаги и распечатайте файл четных страниц.
@mokasin: Вы не сказали, какой читатель PDF вы используете. Если вы используете версию Acrobat/Adobe Reader для Linux: есть возможность напечатать "2-вверх" прямо в диалоговом окне печати. Вы также можете распечатать только нечетные или четные страницы, поэтому комбинирование этого поможет вам достичь желаемого результата.
решение сpython
(PyPDF2
версия 3.0.1)
вход (слева)/выход (справа)
Применение
Скорее всего вам нужно установить PyPDF2 (в указанной версии) с помощью
pip install PyPDF2==3.0.1
Затем вы можете выполнить скрипт с помощью
python create_multipage_pdf.py demo.pdf
код
Интервал и количество страниц (n_rows, n_cols) настраиваются. Вы также можете перевести выходной PDF-файл в альбомный режим, выполнивROTATE_OUTPUT = 90
.
create_multipage_pdf.py
PAGE_SHAPE_OUT = (297, 210) # width, height
PAGES_PER_SHEET = (2, 2) # n_rows, n_cols
PAD_LEFT = 20
PAD_RIGHT = 20
PAD_TOP = 20
PAD_BOTTOM = 20
WSPACE = 10
HSPACE = 20
ROTATE_OUTPUT = 0
FN_OUT_SEP = "_"
FN_OUT_SUFFIX = "multipage.pdf"
import sys
import PyPDF2
from math import prod
def add_page(doc_out, page, rects):
"""add page to PdfWriter and draw rectangle around subpages"""
doc_out.add_page(page.rotate(ROTATE_OUTPUT))
for rect in rects:
# rect boarder is drawn inside
pad = 1
rect_padded = (rect[0] - pad, rect[1] - pad, rect[2] + pad, rect[3] + pad)
doc_out.add_annotation(-1, PyPDF2.generic.AnnotationBuilder.rectangle(rect=rect_padded))
def main():
global FNS_IN
if len(sys.argv) > 1:
FNS_IN = sys.argv[1:]
fn_out = FN_OUT_SUFFIX
if len(sys.argv) == 2:
fn_out = FNS_IN[0][:-4] + FN_OUT_SEP + FN_OUT_SUFFIX
doc_out = PyPDF2.PdfWriter()
pos = 0
page = None
for filename in FNS_IN:
doc_in = PyPDF2.PdfReader(open(filename, "rb"))
for pp in range(0, len(doc_in.pages)):
if pos % prod(PAGES_PER_SHEET) == 0:
if page is not None:
add_page(doc_out, page, rects)
page = PyPDF2.PageObject.create_blank_page(None, *PAGE_SHAPE_OUT)
rects = []
page_in = doc_in.pages[pp]
# scale
page_in_width = float(page_in.mediabox[2])
page_in_height = float(page_in.mediabox[3])
page_in_width_available = (
(PAGE_SHAPE_OUT[0] - PAD_LEFT - PAD_RIGHT - WSPACE*(PAGES_PER_SHEET[0] - 1))
/ PAGES_PER_SHEET[0]
)
page_in_height_available = (
(PAGE_SHAPE_OUT[1] - PAD_TOP - PAD_BOTTOM - HSPACE*(PAGES_PER_SHEET[1] - 1))
/ PAGES_PER_SHEET[1]
)
scale = min(page_in_width_available/page_in_width, page_in_height_available/page_in_height)
page_in_width_scaled = page_in_width * scale
page_in_height_scaled = page_in_height * scale
# pos
pos_page = pos % prod(PAGES_PER_SHEET)
pos_row = pos_page // PAGES_PER_SHEET[1]
pos_col = pos_page % PAGES_PER_SHEET[1]
pos_x = PAD_LEFT + (WSPACE + page_in_width_available) * pos_col
pos_y = PAD_BOTTOM + (HSPACE + page_in_height_available) * (PAGES_PER_SHEET[1] - 1 - pos_row)
# rects
rects += [(pos_x, pos_y, pos_x + page_in_width_scaled, pos_y + page_in_height_scaled)]
tansformation = PyPDF2.Transformation().scale(scale).translate(tx=pos_x, ty=pos_y)
page_in.add_transformation(tansformation)
page.merge_page(page_in)
pos += 1
add_page(doc_out=doc_out, page=page, rects=rects)
doc_out.write(open(fn_out, "wb"))
if __name__ == "__main__":
assert len(sys.argv) >= 2, "call python script with at least one argument (pdfs to be multipaged)"
main()
Информация
- вдохновленный этим ответом: /questions/938052/kak-preobrazovat-1-stranichnyij-pdf-fajl-v-dvuhstranichnyij-pdf-fajl/1114467#1114467
- Я еще не работал с PDF-файлами, так что это было хорошее упражнение. Однако не уверен, буду ли я снова использовать PyPDF2 для будущих проектов...
pdfnup устарел или исчез из дистрибутивов.
Но pdfautonup — замечательная замена, которая работает так же просто:
pdfautonup foo.pdf