Bash Script to scale and/or resize PDFs from the command line.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 

193 lignes
5.5 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.9"
  12. SCALE="0.95" # scaling factor (0.95 = 95%, e.g.)
  13. VERBOSE=0 # verbosity Level
  14. BASENAME="$(basename $0)" # simplified name of this script
  15. GSBIN="" # Set with which after we check dependencies
  16. BCBIN="" # Set with which after we check dependencies
  17. LC_MEASUREMENT="C" # To make sure our numbers have .decimals
  18. LC_ALL="C" # Some languages use , as decimal token
  19. LC_CTYPE="C"
  20. LC_NUMERIC="C"
  21. printVersion() {
  22. if [[ $1 -eq 2 ]]; then
  23. echo >&2 "$BASENAME v$VERSION"
  24. else
  25. echo "$BASENAME v$VERSION"
  26. fi
  27. }
  28. printHelp() {
  29. printVersion
  30. echo "
  31. Usage: $BASENAME [-v] [-s <factor>] <inFile.pdf> [outfile.pdf]
  32. $BASENAME -h
  33. $BASENAME -V
  34. Parameters:
  35. -v Verbose mode, prints extra information
  36. Use twice for even more information
  37. -h Print this help to screen and exits
  38. -V Prints version to screen and exits
  39. -s <factor> Changes the scaling factor, defaults to 0.95
  40. MUST be a number bigger than zero.
  41. Eg. -s 0.8 for 80% of the original size
  42. Notes:
  43. - Options must be passed before the file names to be parsed
  44. - The output filename is optional. If no file name is passed
  45. the output file will have the same name/destination of the
  46. input file, with .SCALED.pdf at the end (instead of just .pdf)
  47. - Having the extension .pdf on the output file name is optional,
  48. it will be added if not present
  49. - Should handle file names with spaces without problems
  50. - The scaling is centered and using a scale bigger than 1 may
  51. result on cropping parts of the pdf.
  52. Examples:
  53. $BASENAME myPdfFile.pdf
  54. $BASENAME myPdfFile.pdf myScaledPdf
  55. $BASENAME -v -v myPdfFile.pdf
  56. $BASENAME -s 0.85 myPdfFile.pdf myScaledPdf.pdf
  57. $BASENAME -v -v -s 0.7 myPdfFile.pdf
  58. $BASENAME -h
  59. "
  60. }
  61. usage() {
  62. printVersion 2
  63. echo >&2 "Usage: $0 [-v] [-s <factor>] <inFile.pdf> [outfile.pdf]"
  64. echo >&2 "Try: $0 -h # for help"
  65. exit 1
  66. }
  67. vprint() {
  68. [[ $VERBOSE -eq 0 ]] && return 0
  69. timestamp=""
  70. [[ $VERBOSE -gt 1 ]] && timestamp="$(date +%Y-%m-%d:%H:%M:%S) | "
  71. echo "$timestamp$1"
  72. }
  73. printDependency() {
  74. printVersion 2
  75. echo >&2 $'\n'"ERROR! You need to install the package '$1'"$'\n'
  76. echo >&2 "Linux apt-get.: sudo apt-get install $1"
  77. echo >&2 "Linux yum.....: sudo yum install $1"
  78. echo >&2 "MacOS homebrew: brew install $1"
  79. echo >&2 $'\n'"Aborting..."
  80. exit 3
  81. }
  82. parseScale() {
  83. if ! [[ -n "$1" && "$1" =~ ^-?[0-9]*([.][0-9]+)?$ && (($1 > 0 )) ]] ; then
  84. echo >&2 "Invalid factor: $1"
  85. echo >&2 "The factor must be a floating point number greater than 0"
  86. echo >&2 "Example: for 80% use 0.8"
  87. exit 2
  88. fi
  89. SCALE=$1
  90. }
  91. getPageSize() {
  92. # get MediaBox info from PDF file using cat and grep, these are all possible
  93. # /MediaBox [0 0 595 841]
  94. # /MediaBox [ 0 0 595.28 841.89]
  95. # /MediaBox[ 0 0 595.28 841.89 ]
  96. local mediaBox="$(cat "$INFILEPDF" | grep -a '/MediaBox')" # done with externals
  97. findex=$(expr index "$mediaBox" "0") # Find first Zero
  98. findex=$(($findex+3)) # Adjust postion to 1st number
  99. mediaBox="${mediaBox:$findex}" # Re-set base string
  100. findex=$(expr index "$mediaBox" ' ') # Tokenize
  101. PGWIDTH=$(printf '%.0f' "${mediaBox:0:(($findex-1))}") # Get Round Width
  102. mediaBox="${mediaBox:$findex}" # Re-set base string
  103. findex=$(expr index "$mediaBox" ' ') # Ends with space or ]
  104. [[ $findex -eq 0 ]] && findex=$(expr index "$mediaBox" ']')
  105. PGHEIGHT=$(printf '%.0f' "${mediaBox:0:(($findex-1))}") # Get Round Height
  106. vprint " Width: $PGWIDTH postscript-points"
  107. vprint " Height: $PGHEIGHT postscript-points"
  108. }
  109. while getopts ":vhVs:" o; do
  110. case "${o}" in
  111. v)
  112. ((VERBOSE++))
  113. ;;
  114. h)
  115. printHelp
  116. exit 0
  117. ;;
  118. V)
  119. printVersion
  120. exit 0
  121. ;;
  122. s)
  123. parseScale ${OPTARG}
  124. ;;
  125. *)
  126. usage
  127. ;;
  128. esac
  129. done
  130. shift $((OPTIND-1))
  131. vprint "$(basename $0) v$VERSION - Verbose execution"
  132. # Dependencies
  133. vprint "Checking dependencies"
  134. command -v gs >/dev/null 2>&1 || printDependency 'ghostscript'
  135. command -v bc >/dev/null 2>&1 || printDependency 'bc'
  136. GSBIN=$(which gs 2>/dev/null)
  137. BCBIN=$(which bc 2>/dev/null)
  138. vprint " Scale factor: $SCALE"
  139. # Validate args
  140. [[ $# -lt 1 ]] && { usage; exit 1; }
  141. INFILEPDF="$1"
  142. [[ "$INFILEPDF" =~ ^..*\.pdf$ ]] || { usage; exit 2; }
  143. vprint " Input file: $INFILEPDF"
  144. # Parse output filename
  145. if [[ -z $2 ]]; then
  146. OUTFILEPDF="${INFILEPDF%.pdf}.SCALED.pdf"
  147. else
  148. OUTFILEPDF="${2%.pdf}.pdf"
  149. fi
  150. vprint " Output file: $OUTFILEPDF"
  151. # Set PGWIDTH and PGHEIGHT
  152. getPageSize
  153. # Compute translation factors (to center page.
  154. XTRANS=$(echo "scale=6; 0.5*(1.0-$SCALE)/$SCALE*$PGWIDTH" | "$BCBIN")
  155. YTRANS=$(echo "scale=6; 0.5*(1.0-$SCALE)/$SCALE*$PGHEIGHT" | "$BCBIN")
  156. vprint " Translation X: $XTRANS"
  157. vprint " Translation Y: $YTRANS"
  158. # Do it.
  159. "$GSBIN" \
  160. -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dSAFER \
  161. -dCompatibilityLevel="1.5" -dPDFSETTINGS="/printer" \
  162. -dColorConversionStrategy=/LeaveColorUnchanged \
  163. -dSubsetFonts=true -dEmbedAllFonts=true \
  164. -dDEVICEWIDTH=$PGWIDTH -dDEVICEHEIGHT=$PGHEIGHT \
  165. -sOutputFile="$OUTFILEPDF" \
  166. -c "<</BeginPage{$SCALE $SCALE scale $XTRANS $YTRANS translate}>> setpagedevice" \
  167. -f "$INFILEPDF"