Bash Script to scale and/or resize PDFs from the command line.
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 

193 rindas
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.7"
  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: $0 [-v] [-s <factor>] <inFile.pdf> [outfile.pdf]
  32. $0 -h
  33. $0 -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. pdfScale myPdfFile.pdf
  54. pdfScale myPdfFile.pdf myScaledPdf
  55. pdfScale -v -v myPdfFile.pdf
  56. pdfScale -s 0.85 myPdfFile.pdf myScaledPdf.pdf
  57. pdfScale -v -v -s 0.7 myPdfFile.pdf
  58. pdfScale -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 number between 0 and 1."
  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"