PDF Operations

A lot of things done with PDFs are using ghostscript-commands. This page is for other things, or multistep operations.

Shift a PDF sideways

A double-sided PDF that is slightly offset from the edge may need to be shifted one way or other. These commands shift both pages towards the binding by about 3mm:

convert -density 300 "Input PDF.pdf" -quality 100 -fuzz 1% -fill white -draw "color 0,0 floodfill"  "output-PNGs.png"
convert "output-PNGs-0.png" -page -9.44+0 -background none "output-PNGs-0_offset.png
convert "output-PNGs-1.png" -page +9.44+0 -background none "output-PNGs_offset.png
convert "output-PNGs-0_offset.png" "output-PNGs-1_offset.png" -density 300 "Output PDF.pdf"

rem "Shifts the PDF by about 3mm (page 0 shifted left, page 1 shifted right)"

These commands use ImageMagick convert, but GhostScript must be installed for them to work. This is primarily for use in Windows, but can be adapted for other systems.

Reverse a PDF

This command reverses the order of pages in a PDF.

pdftk "in.pdf" cat end-1 output "out.pdf"

Split 2-Page Spread PDF into Single-Page-Per-Sheet PDF

I was sent a 30 page PDF where pages 2 to 29 were done as 2-page spreads, so could not be easily printed. It took about 4 hours to figure out, but I managed to cobble together a basic shell script that could split the pages into an ordinary 1-page-per-sheet PDF. In addition to the standard shell tools, this uses ImageMagick and GhostScript. Sadly, to be able to do the splits and retain the quality, I had to turn the PDF into one comprised of high-quality images, which resulted in the 2MB PDF growing to about 65MB and taking ages to process for printing, so this is not an ideal solution. However, given the time taken to figure this out, I was not willing to spend more time trying to find a way to shrink the filesize while still keeping the quality.

NumPages="15"		# Number of pages in PDF
InputPDF="input.pdf"	# Name of PDF to input
OutputPDF="output.pdf"	# Name of PDF to output
alias GScript="gs"	# When using on Windows, this should be changed from "gs" to "gswin64c"

GScript -q -dBATCH -dNOPAUSE -sDEVICE=png16malpha -dFirstPage=1 "-dLastPage=$NumPages" \
    "-sOutputFile=Output%d_sep.png" -r1200 "$InputPDF"	# Extract pages into individual images
for i in `seq 2 $(dc -e "$NumPages 1 - p")`; do \
    dub="$(printf "%02d" "$(dc -e "$i 2 * 1 - p")")"; \
    echo "PDF Page $i = Pages $(dc -e "$dub 1 - p")-$dub"; \
    mv "Output${i}_sep.png" "part${dub}_both.png";  convert "part${dub}_both.png" -set filename:fname "%[t]" \
      -write mpr:img +delete \( mpr:img -gravity west -crop 50x100%+0+0 +repage +write \
      "PNG24:part$(printf "%02d" "$(dc -e "$dub 1 - p")").png" \) \( mpr:img -gravity east -crop \
      50x100%+0+0 +repage +write "PNG24:part${dub}.png" \) info:; \
    done	# Split pages 2 to NumPages-1 into two and number the images accordingly.
mv "Output1_sep.png" "part01.png"; mv "Output${NumPages}_sep.png" \
    "part$(printf "%02d" "$(dc -e "$NumPages 1 - 2 * p")").png"	# Number the first and last images to fit.
convert part??.png  "$OutputPDF"	# Convert the images back into a PDF.

Notes

It seems that despite having converted the PDF to 1200dpi images (to retain commercial print quality), the final command should not be:

convert part??.png -density 1200 "$OutputPDF"

as this drops the size of the resulting PDF. I think the DPI is embedded in the images, so forcing it confuses ImageMagick.

I tried a variety of other splitting techniques with ImageMagick, but this one worked best:

convert "part${dub}_both.png" -set filename:fname "%[t]" -write mpr:img +delete \
    \( mpr:img -gravity west -crop 50x100%+0+0 +repage +write "PNG24:part$(printf "%02d" \
    "$(dc -e "$dub 1 - p")").png" \) \( mpr:img -gravity east -crop 50x100%+0+0 +repage +write \
    "PNG24:part${dub}.png" \) info:

(Commands I tried and discarded included variants of:

mogrify -crop 50%x100% +repage -path ./split -format PNG24 "PNG24:part${dub}_both.png"

and:

convert input.png -set filename:0 "%[t]" \( -alpha copy +clone -roll +50+0% \) -extent 50x100% \
    -alpha Set "PNG24:%[filename:0]_%d.png"

but these proved fruitless. I include them here as a warning to others.)

Sources

https://ghostscript.readthedocs.io/en/latest/Devices.html for PNG16malpha device
https://stackoverflow.com/questions/71509875/imagemagick-split-image-into-two-with-55-of-original-image-each#71518149 for splitting the images
https://github.com/ImageMagick/ImageMagick/discussions/3453 for retaining PNG24
https://stackoverflow.com/questions/47453839/use-imagemagick-to-combine-multiple-pngs-into-single-pdf for final merge
Some General help
More General help
Further General help