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.
 
 

166 lines
4.5 KiB

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