
У меня есть несколько электронных книг, отсканированных с оригиналов. Они отформатированы так, что однаPDF-страницасодержит двафактические страницы: один слева и один справа.
Я хочу программно разделить каждую страницу PDF-файла на две части, так чтобы левые 50% страницы 1 PDF-файла стали страницей 1, а ее правые — страницей 2, и так далее для всех страниц.
Кто-нибудь знает утилиту командной строки или скрипт, который мог бы помочь в этом?
Вывод из pdfimages -list -f 1 -l 1 file.pdf
:
page num type width height color comp bpc enc interp object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
1 0 image 1921 1561 rgb 3 8 jpeg no 643 0 200 200 200K 2.3%
1 1 stencil 1 1 - 1 1 image no [inline] 0.692 2 - -
1 2 stencil 1 1 - 1 1 image no [inline] 0.722 0.650 - -
1 3 stencil 1 1 - 1 1 image no [inline] 3 3 - -
Второй PDF-файл:
page num type width height color comp bpc enc interp object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
1 0 image 456 625 gray 1 8 jpx yes 251 0 72 72 11.7K 4.2%
решение1
Это должно сработать, нужен pdftk
инструмент (и ghostscript
).
Простой случай:
Первый шаг:Разделить на отдельные страницы
pdftk clpdf.pdf burst
это создает файлы pg_0001.pdf, pg_0002.pdf, ... pg_NNNN.pdf
, по одному для каждой страницы. Это также создает, doc_data.txt
который содержит размеры страницы.
Шаг второй:Создать левую и правую половину страницы
pw=`cat doc_data.txt | grep PageMediaDimensions | head -1 | awk '{print $2}'`
ph=`cat doc_data.txt | grep PageMediaDimensions | head -1 | awk '{print $3}'`
w2=$(( pw / 2 ))
w2px=$(( w2*10 ))
hpx=$(( ph*10 ))
for f in pg_[0-9]*.pdf ; do
lf=left_$f
rf=right_$f
gs -o ${lf} -sDEVICE=pdfwrite -g${w2px}x${hpx} -c "<</PageOffset [0 0]>> setpagedevice" -f ${f}
gs -o ${rf} -sDEVICE=pdfwrite -g${w2px}x${hpx} -c "<</PageOffset [-${w2} 0]>> setpagedevice" -f ${f}
done
Шаг третий:Объедините левое и правое, чтобы создать newfile.pdf
файл .pdf, содержащий одну страницу.
ls -1 [lr]*_[0-9]*pdf | sort -n -k3 -t_ > fl
pdftk `cat fl` cat output newfile.pdf
Более общий случай:
В примере выше предполагается, что все страницы имеют одинаковый размер.
doc_data.txt
Файл содержит размер для каждой разделенной страницы. Если командаgrep PageMediaDimensions <doc_data.txt | sort | uniq | wc -l
не возвращает 1, то страницы имеют разные размеры и необходима дополнительная логика.Шаг второй.
Если соотношение не точно 50:50, то
w2=$(( pw / 2 ))
необходима более совершенная формула, чем та, что использована в примере выше.
Во втором примере показано, как обрабатывать этот более общий случай.
Первый шаг:разделить с pdftk
как и прежде
Шаг второй:Теперь создайте три файла, содержащие ширину и высоту каждой страницы, а также значение по умолчанию для доли разделения, которую будет использовать левая страница.
grep PageMediaDimensions <doc_data.txt | awk '{print $2}' > pws.txt
grep PageMediaDimensions <doc_data.txt | awk '{print $3}' > phs.txt
grep PageMediaDimensions <doc_data.txt | awk '{print "0.5"}' > lfrac.txt
файл lfrac.txt
можно редактировать вручную, если доступна информация о том, где следует разбить различные страницы.
Шаг третий:Теперь создайте левую и правую разделенные страницы, используя разные размеры страниц и (если отредактировано) разные дробные местоположения для разделения.
#!/bin/bash
exec 3<pws.txt
exec 4<phs.txt
exec 5<lfrac.txt
for f in pg_[0-9]*.pdf ; do
read <&3 pwloc
read <&4 phloc
read <&5 lfr
wl=`echo "($lfr)"'*'"$pwloc" | bc -l`;wl=`printf "%0.f" $wl`
wr=$(( pwloc - wl ))
lf=left_$f
rf=right_$f
hpx=$(( phloc*10 ))
w2px=$(( wl*10 ))
gs -o ${lf} -sDEVICE=pdfwrite -g${w2px}x${hpx} -c "<</PageOffset [0 0]>> setpagedevice" -f ${f}
w2px=$(( wr*10 ))
gs -o ${rf} -sDEVICE=pdfwrite -g${w2px}x${hpx} -c "<</PageOffset [-${wl} 0]>> setpagedevice" -f ${f}
done
Шаг четвертый:Это тот же шаг слияния, что и в предыдущем, более простом примере.
ls -1 [lr]*_[0-9]*pdf | sort -n -k3 -t_ > fl
pdftk `cat fl` cat output newfile.pdf
решение2
Вы можете расширить свой выбор инструментов, преобразовав PDF-файл в PostScript следующим образом, а затем используяpstops. Я предположил, что мы начнем со страницы формата А4 в портретной ориентации, на которой показаны две страницы, как если бы они были отсканированы из открытой книги, с корешком, проходящим горизонтально через середину, вот так:
Разумеется, вы можете изменить значения в решении ниже, чтобы они соответствовали вашему конкретному случаю.
Вы можете преобразовать этот pdf в PostScript с помощью pdf2ps
(который является частью пакета ghostscript). Затем инструмент pstops
из пакета psutils можно использовать для поворота страницы вправо (по часовой стрелке) вокруг нижнего левого угла, масштабирования и перемещения результата вверх так, чтобы только нижняя половина покрывала всю страницу:
Вторую страницу можно создать из той же исходной страницы с помощью аналогичного поворота, масштабирования и перевода. Результат можно преобразовать обратно в pdf. Одна команда может нарисовать каждую страницу на 2 новых страницах:
pdf2ps myfile.pdf out.ps
pstops -p a4 '[email protected](1cm,29cm),[email protected](-16cm,29cm)' out.ps new.ps
ps2pdf new.ps new.pdf
Синтаксис объясняется на странице руководства. Здесь у нас есть R
для поворота вправо, @1.2 для масштабирования, (x,y) для перемещения результата. Запятая (,) создает 2 страницы из каждой исходной страницы.
Обратите внимание, что это удвоит размер итогового PDF-файла, поскольку каждая страница полностью прорисовывается дважды, даже если вы каждый раз видите только ее половину.
решение3
решение4
Возможно, вам будет интересно посмотреть imagemagick
:
$ convert -resize 1000x1000 /links/www/Salix/pdf/index.pdf a.jpg
$ convert -crop 500x1000+0+0 a.jpg b.jpg
$ convert -crop 500x1000+500+0 a.jpg c.jpg
$ convert c.jpg c.pdf
$ convert b.jpg b.pdf