PDF compression program
10K+

# Ghostscript (gs) quick notes (Markdown-style)
# - Basic:
# gs -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -dQUIET -sOutputFile=OUT.pdf IN.pdf
# - Key options:
# -sDEVICE=pdfwrite : write PDF output
# -dPDFSETTINGS=/screen|/ebook|/printer|/prepress : size vs quality preset
# -dCompatibilityLevel=1.4 : output PDF version
# -dFirstPage=N -dLastPage=M : process a page range
# - Simple examples:
# gs -sDEVICE=pdfwrite -dPDFSETTINGS=/screen -dNOPAUSE -dBATCH -dQUIET -sOutputFile=out.pdf in.pdf
# gs -sDEVICE=pdfwrite -dPDFSETTINGS=/ebook -dNOPAUSE -dBATCH -dQUIET -sOutputFile=out.pdf in.pdf
gs -sDEVICE=pdfwrite -dPDFSETTINGS=/screen -dNOPAUSE -dBATCH -dQUIET -sOutputFile=out.pdf in.pdf
#!/usr/bin/env bash
set -euo pipefail
# Input/Output arguments
sIn="${1:?Usage: $0 input.pdf [output.pdf] [jobs] [dpi] [preset(screen|ebook|printer|prepress)]}"
sOut="${2:-out_parallel.pdf}"
nJobs="${3:-4}"
nDpi="${4:-120}"
sPreset="${5:-screen}"
# Auto-detect page count (prefer qpdf; fallback to pdfinfo)
nPages="$(qpdf --show-npages "$sIn" 2>/dev/null || true)"
if [[ -z "${nPages}" ]]; then
nPages="$(pdfinfo "$sIn" | awk '/^Pages:/ {print $2}')"
fi
if [[ -z "${nPages}" ]]; then
echo "ERROR: cannot detect page count (need qpdf or poppler-utils(pdfinfo))" >&2
exit 1
fi
# Compute pages per chunk (ceil division)
nChunk=$(( (nPages + nJobs - 1) / nJobs ))
# Create a temporary working directory and ensure cleanup on exit
sTmpDir="$(mktemp -d)"
trap 'rm -rf "$sTmpDir"' EXIT
# Ghostscript arguments for PDF recompression/downsampling
sGsArgs="-sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/${sPreset} \
-dDownsampleColorImages=true -dColorImageResolution=${nDpi} \
-dDownsampleGrayImages=true -dGrayImageResolution=${nDpi} \
-dDownsampleMonoImages=true -dMonoImageResolution=300 \
-dNOPAUSE -dBATCH -dQUIET"
# Generate page ranges for parallel processing
sRanges="${sTmpDir}/ranges.txt"
nStart=1
nPart=1
while (( nStart <= nPages )); do
nEnd=$(( nStart + nChunk - 1 ))
(( nEnd > nPages )) && nEnd="${nPages}"
printf "%04d %d %d\n" "${nPart}" "${nStart}" "${nEnd}" >> "${sRanges}"
nStart=$(( nEnd + 1 ))
nPart=$(( nPart + 1 ))
done
# Run Ghostscript in parallel for each page range
cat "${sRanges}" | xargs -n3 -P "${nJobs}" bash -c '
sPart="$0"; nFirst="$1"; nLast="$2";
sOutPart="'"${sTmpDir}"'/part_${sPart}.pdf"
gs '"${sGsArgs}"' -dFirstPage="${nFirst}" -dLastPage="${nLast}" -sOutputFile="${sOutPart}" "'"${sIn}"'"
'
# Merge generated parts (keeps order: part_0001.pdf, part_0002.pdf, ...)
qpdf --empty --pages "${sTmpDir}"/part_*.pdf -- "${sOut}"
# Final summary
echo "DONE: ${sOut} (pages=${nPages}, jobs=${nJobs}, dpi=${nDpi}, preset=${sPreset})"
Content type
Image
Digest
sha256:d82cbeebf…
Size
129.1 MB
Last updated
9 months ago
docker pull shinejh0528/ghostscript:1.0.0