Last active
April 24, 2023 12:49
-
-
Save rxa254/ca8bab43a627040a473762b43d96bda7 to your computer and use it in GitHub Desktop.
How to compress PDF files from the command line
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Author: Sylvain Carlioz | |
# 6/03/2017 | |
# MIT license -- free to use as you want, cheers. | |
# | |
# rxa254@github.com | |
# modified Jan/2019 | |
# changed input args so it can run on a whole directory | |
""" | |
Simple python wrapper script to use ghoscript function to compress PDF files. | |
Compression levels: | |
0: default | |
1: prepress | |
2: printer | |
3: ebook | |
4: screen | |
Dependency: Ghostscript. | |
On MacOSX install via command line `brew install ghostscript`. | |
""" | |
import argparse | |
import subprocess | |
import os | |
import sys | |
from shutil import copyfile | |
def compress(input_file_path, output_file_path, power=0): | |
"""Function to compress PDF via Ghostscript command line interface""" | |
quality = { | |
0: '/default', | |
1: '/prepress', | |
2: '/printer', | |
3: '/ebook', | |
4: '/screen' | |
} | |
# Basic controls | |
# Check if valid path | |
if not os.path.isfile(input_file_path): | |
print("Error: invalid path for input PDF file") | |
sys.exit(1) | |
# Check if file is a PDF by extension | |
if input_file_path.split('.')[-1].lower() != 'pdf': | |
print("Error: input file is not a PDF") | |
sys.exit(1) | |
print("Compress PDF...") | |
initial_size = os.path.getsize(input_file_path) | |
subprocess.call(['gs', '-sDEVICE=pdfwrite', '-dCompatibilityLevel=1.6', | |
'-dPDFSETTINGS={}'.format(quality[power]), | |
'-dNOPAUSE', '-dQUIET', '-dBATCH', | |
'-sOutputFile={}'.format(output_file_path), | |
input_file_path] | |
) | |
final_size = os.path.getsize(output_file_path) | |
ratio = 1 - (final_size / initial_size) | |
print("Compression by {0:.0%}.".format(ratio)) | |
print("Final file size is {0:.1f}MB".format(final_size / 1000000)) | |
print("Done.") | |
def main(): | |
parser = argparse.ArgumentParser( | |
description=__doc__, | |
formatter_class=argparse.RawDescriptionHelpFormatter | |
) | |
parser.add_argument('--input', help='Relative or absolute path of the input PDF file') | |
parser.add_argument('-o', '--out', help='Relative or absolute path of the output PDF file') | |
parser.add_argument('-c', '--compress', type=int, help='Compression level from 0 to 4') | |
parser.add_argument('--all', action='store_true', default=False, | |
help='Compress all PDFs in this directory !!!') | |
args = parser.parse_args() | |
# In case no compression level is specified, default is 2 '/ printer' | |
if not args.compress: | |
args.compress = 2 | |
# In case no output file is specified, store in temp file | |
if not args.out: | |
args.out = 'temp.pdf' | |
if args.all: | |
for filename in os.listdir('.'): | |
if filename.endswith(".pdf"): | |
print(filename) | |
compress(filename, 'tuttut.pdf', power=args.compress) | |
copyfile( 'tuttut.pdf', filename) | |
os.remove('tuttut.pdf') | |
else: | |
# Run | |
compress(args.input, args.out, power=args.compress) | |
# In case no output file is specified, erase original file | |
if args.out == 'temp.pdf' and not args.all: | |
copyfile(args.out, args.input) | |
os.remove(args.out) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment