Skip to content

Instantly share code, notes, and snippets.

@Akhrameev
Created December 2, 2025 14:46
Show Gist options
  • Select an option

  • Save Akhrameev/ea90d61f003256ef0ad4fc00c273a8d0 to your computer and use it in GitHub Desktop.

Select an option

Save Akhrameev/ea90d61f003256ef0ad4fc00c273a8d0 to your computer and use it in GitHub Desktop.
The Code Behind "The Grayscale Paradox". Full story in my LinkedIn article.
import os
import subprocess
import shutil
import sys
import argparse # The standard library for parsing command-line arguments
# --- Configuration ---
# The template for the output subdirectory. It will now include the mode (color/grayscale).
OUTPUT_SUBDIR_TEMPLATE = 'compressed_{dpi}dpi_{mode}'
# --- End of Configuration ---
def compress_pdfs(input_directory, dpi_value, make_grayscale):
"""
Finds and compresses all PDF files in the specified directory using Ghostscript.
"""
# 1. Verify Ghostscript is installed and accessible.
if not shutil.which('gs'):
print("ERROR: Ghostscript ('gs') is not installed or not in your system's PATH.")
print("Please install it. On macOS, you can use Homebrew: 'brew install ghostscript'")
sys.exit(1)
# 2. Set up input and output paths dynamically.
input_dir = os.path.expanduser(input_directory)
color_mode_str = "grayscale" if make_grayscale else "color"
output_subdir_name = OUTPUT_SUBDIR_TEMPLATE.format(dpi=dpi_value, mode=color_mode_str)
output_dir = os.path.join(input_dir, output_subdir_name)
if not os.path.isdir(input_dir):
print(f"ERROR: The specified input directory does not exist: {input_dir}")
sys.exit(1)
# 3. Create the output subdirectory.
os.makedirs(output_dir, exist_ok=True)
print(f"✅ Script started. Target DPI: {dpi_value}, Mode: {color_mode_str}")
print(f"Compressed files will be saved in: {output_dir}")
print("-" * 30)
# 4. Loop through all files in the input directory.
found_pdfs = False
for filename in os.listdir(input_dir):
if filename.lower().endswith('.pdf'):
found_pdfs = True
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
print(f"Processing '{filename}'...")
# 5. Conditionally build the Ghostscript command.
# Start with the parts that are common to both modes.
command = [
'gs',
'-sDEVICE=pdfwrite',
'-dCompatibilityLevel=1.4',
'-dNOPAUSE',
'-dQUIET',
'-dBATCH'
]
# Add mode-specific arguments
if make_grayscale:
command.extend([
'-sProcessColorModel=DeviceGray',
'-sColorConversionStrategy=Gray',
f'-dGrayImageResolution={dpi_value}',
'-dDownsampleGrayImages=true'
])
else: # Color mode
command.extend([
f'-dColorImageResolution={dpi_value}',
'-dDownsampleColorImages=true'
])
# Add the final output and input file paths
command.extend([
f'-sOutputFile={output_path}',
input_path
])
# 6. Run the command and report status.
try:
subprocess.run(command, check=True, capture_output=True, text=True)
original_size = os.path.getsize(input_path) / (1024 * 1024)
compressed_size = os.path.getsize(output_path) / (1024 * 1024)
reduction = (1 - compressed_size / original_size) * 100 if original_size > 0 else 0
print(f" └── SUCCESS: Reduced from {original_size:.2f} MB to {compressed_size:.2f} MB ({reduction:.1f}% reduction).")
except subprocess.CalledProcessError as e:
print(f" └── ERROR compressing '{filename}'.")
print(f" Ghostscript error message: {e.stderr}")
if not found_pdfs:
print("No PDF files were found in the specified directory.")
print("-" * 30)
print("✅ All done!")
if __name__ == '__main__':
# --- Argument Parsing Setup ---
parser = argparse.ArgumentParser(
description="A script to compress all PDF files in a directory using Ghostscript.",
formatter_class=argparse.RawTextHelpFormatter
)
parser.add_argument(
"input_directory",
help="The full path to the directory containing the PDFs you want to compress."
)
parser.add_argument(
"--dpi",
type=int,
default=120,
help="The target resolution in DPI (Dots Per Inch) for images.\n"
"A lower number means a smaller file size but lower quality.\n"
"Default: 120"
)
parser.add_argument(
"--grayscale",
action="store_true", # This makes it a boolean flag. If present, it's True.
help="Convert the output PDFs to grayscale (black and white).\n"
"If this flag is not included, the output will be in color."
)
args = parser.parse_args()
if args.dpi <= 0:
print("ERROR: DPI value must be a positive number.")
sys.exit(1)
# Call the main function with the parsed arguments
compress_pdfs(args.input_directory, args.dpi, args.grayscale)
@Akhrameev
Copy link
Author

Akhrameev commented Dec 2, 2025

The Code Behind "The Grayscale Paradox"
A Python script I wrote to solve an insane 62 MB to 4 MB compression problem for my family's Canadian permanent residence application. Is uses open-source tools like Ghostscript to achieve what simple online converters couldn't.
I'm sharing it here for anyone else facing a similar bureaucratic-technical challenge. Full story in my LinkedIn article.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment