Bash Script to scale and/or resize PDFs from the command line.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

169 line
4.6 KiB

  1. #!/usr/bin/env bash
  2. # pdfScale.sh
  3. #
  4. # Scale PDF to specified percentage of original size.
  5. #
  6. # Gutavo Arnosti Neves - 2016 / 07 / 10
  7. #
  8. # This script: https://github.com/tavinus/pdfScale
  9. # Based on: http://ma.juii.net/blog/scale-page-content-of-pdf-files
  10. # And: https://gist.github.com/MichaelJCole/86e4968dbfc13256228a
  11. VERSION="1.0.5"
  12. SCALE=0.95 # scaling factor (0.95 = 95%, e.g.)
  13. VERBOSE=0 # verbosity Level
  14. printVersion() {
  15. echo "$(basename $0) v$VERSION"
  16. }
  17. printHelp() {
  18. printVersion
  19. echo "
  20. Usage: $0 [-v] [-s <factor>] <inFile.pdf> [outfile.pdf]
  21. $0 -h
  22. $0 -V
  23. Parameters:
  24. -v Verbose mode, prints extra information
  25. -h Print this help to screen and exits
  26. -V Prints version to screen and exits
  27. -s <factor> Changes the scaling factor, defaults to 0.95
  28. MUST be a number bigger than zero.
  29. Eg. -s 0.8 for 80% of the original size
  30. Notes:
  31. - Options must be passed before the file names to be parsed
  32. - The output filename is optional. If no file name is passed
  33. the output file will have the same name/destination of the
  34. input file, with .SCALED.pdf at the end (instead of just .pdf)
  35. - Having the extension .pdf on the output file name is optional,
  36. it will be added if not present
  37. - Should handle file names with spaces without problems
  38. - The scaling is centered and using a scale bigger than 1 may
  39. result on cropping parts of the pdf.
  40. Examples:
  41. pdfScale myPdfFile.pdf
  42. pdfScale myPdfFile.pdf myScaledPdf
  43. pdfScale -v myPdfFile.pdf
  44. pdfScale -s 0.85 myPdfFile.pdf myScaledPdf.pdf
  45. pdfScale -v -s 0.7 myPdfFile.pdf
  46. pdfScale -h
  47. "
  48. }
  49. usage() {
  50. printVersion
  51. echo "Usage: $0 [-v] [-s <factor>] <inFile.pdf> [outfile.pdf]" 1>&2
  52. echo "Try: $0 -h # for help" 1>&2
  53. exit 1
  54. }
  55. parseScale() {
  56. if ! [[ -n "$1" && "$1" =~ ^-?[0-9]*([.][0-9]+)?$ && (($1 > 0 )) ]] ; then
  57. echo "Invalid factor: $1"
  58. echo "The factor must be a number between 0 and 1."
  59. echo "Example: for 80% use 0.8"
  60. exit 2
  61. fi
  62. SCALE=$1
  63. }
  64. vprint() {
  65. [[ $VERBOSE -eq 0 ]] && return 0
  66. timestamp="$(date +%Y-%m-%d:%H:%M:%S)"
  67. echo "$timestamp | $1"
  68. }
  69. while getopts ":vhVs:" o; do
  70. case "${o}" in
  71. v)
  72. VERBOSE=1
  73. ;;
  74. h)
  75. printHelp
  76. exit 0
  77. ;;
  78. V)
  79. printVersion
  80. exit 0
  81. ;;
  82. s)
  83. parseScale ${OPTARG}
  84. ;;
  85. *)
  86. usage
  87. ;;
  88. esac
  89. done
  90. shift $((OPTIND-1))
  91. printDependency() {
  92. echo >&2 $'\n'"ERROR! You need to install the package '$1'"$'\n'
  93. echo >&2 "Linux apt-get.: sudo apt-get install $1"
  94. echo >&2 "Linux yum.....: sudo yum install $1"
  95. echo >&2 "MacOS homebrew: brew install $1"
  96. echo >&2 $'\n'"Aborting..."
  97. exit 3
  98. }
  99. vprint "$(basename $0) v$VERSION - Verbose execution"
  100. # Dependencies
  101. vprint "Checking dependencies"
  102. command -v identify >/dev/null 2>&1 || printDependency 'imagemagick'
  103. command -v gs >/dev/null 2>&1 || printDependency 'ghostscript'
  104. command -v bc >/dev/null 2>&1 || printDependency 'bc'
  105. vprint " Scale factor: $SCALE"
  106. # Validate args.
  107. [[ $# -lt 1 ]] && { usage; exit 1; }
  108. INFILEPDF="$1"
  109. [[ "$INFILEPDF" =~ ^..*\.pdf$ ]] || { usage; exit 2; }
  110. vprint " Input file: $INFILEPDF"
  111. if [[ -z $2 ]]; then
  112. OUTFILEPDF="${INFILEPDF%.pdf}.SCALED.pdf"
  113. else
  114. OUTFILEPDF="${2%.pdf}.pdf"
  115. fi
  116. vprint " Output file: $OUTFILEPDF"
  117. # Get width/height in postscript points (1/72-inch), via ImageMagick identify command.
  118. # (Alternatively, could use Poppler pdfinfo command; or grep/sed the PDF by hand.)
  119. IDENTIFY=$(identify -format "%G" "$INFILEPDF" 2>/dev/null)
  120. [[ -z $IDENTIFY ]] && { echo "Error when getting PDF size! Aborting..." ; exit 11; }
  121. IDENTIFY="$(echo "$IDENTIFY" | tr "x" " " 2>/dev/null | tr -d "+" 2>/dev/null)"
  122. IDENTIFY=($(echo "$IDENTIFY")) # transform in a bash array
  123. PGWIDTH=${IDENTIFY[0]}
  124. PGHEIGHT=${IDENTIFY[1]}
  125. vprint " Width: $PGWIDTH postscript-points"
  126. vprint " Height: $PGHEIGHT postscript-points"
  127. # Compute translation factors (to center page.
  128. XTRANS=$(echo "scale=6; 0.5*(1.0-$SCALE)/$SCALE*$PGWIDTH" | bc)
  129. YTRANS=$(echo "scale=6; 0.5*(1.0-$SCALE)/$SCALE*$PGHEIGHT" | bc)
  130. vprint " Translation X: $XTRANS"
  131. vprint " Translation Y: $YTRANS"
  132. #echo $PGWIDTH , $PGHEIGHT , $OUTFILEPDF , $SCALE , $XTRANS , $YTRANS , $INFILEPDF , $OUTFILEPDF
  133. # Do it.
  134. gs \
  135. -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dSAFER \
  136. -dCompatibilityLevel="1.5" -dPDFSETTINGS="/printer" \
  137. -dColorConversionStrategy=/LeaveColorUnchanged \
  138. -dSubsetFonts=true -dEmbedAllFonts=true \
  139. -dDEVICEWIDTH=$PGWIDTH -dDEVICEHEIGHT=$PGHEIGHT \
  140. -sOutputFile="$OUTFILEPDF" \
  141. -c "<</BeginPage{$SCALE $SCALE scale $XTRANS $YTRANS translate}>> setpagedevice" \
  142. -f "$INFILEPDF"