pip3 install pymupdf
chmod +x pdf2dark.py
./pdf2dark.py inputfile.pdf -o output.pdf
| #!/usr/bin/env python3 | |
| import fitz # PyMuPDF | |
| import argparse | |
| from pathlib import Path | |
| def convert_to_dark_mode(input_path, output_path): | |
| """ | |
| Convert a PDF to dark mode by rendering pages as images and reconstructing | |
| """ | |
| try: | |
| # Open the input PDF | |
| pdf_document = fitz.open(input_path) | |
| # Create a new PDF for output | |
| out_doc = fitz.open() | |
| for page_num in range(len(pdf_document)): | |
| # Get the original page | |
| page = pdf_document[page_num] | |
| # Create a pixmap of the page with white text on black background | |
| # Using a higher zoom factor for better quality | |
| zoom = 3 # Increase this for higher quality, decrease for better performance | |
| mat = fitz.Matrix(zoom, zoom) | |
| pix = page.get_pixmap(matrix=mat) | |
| # Invert the colors | |
| pix.invert_irect(None) # None means the entire image | |
| # Create a new page in the output PDF | |
| new_page = out_doc.new_page(width=page.rect.width, height=page.rect.height) | |
| # Insert the inverted image into the new page, scaling it back to original size | |
| new_page.insert_image(new_page.rect, pixmap=pix) | |
| # Save the modified PDF | |
| out_doc.save( | |
| output_path, | |
| garbage=4, | |
| deflate=True, | |
| clean=True | |
| ) | |
| # Close documents | |
| out_doc.close() | |
| pdf_document.close() | |
| print(f"Successfully converted PDF to dark mode: {output_path}") | |
| return True | |
| except Exception as e: | |
| print(f"Error converting PDF: {str(e)}") | |
| return False | |
| def main(): | |
| parser = argparse.ArgumentParser(description='Convert a PDF to dark mode') | |
| parser.add_argument('input_pdf', help='Path to the input PDF file') | |
| parser.add_argument('-o', '--output', help='Path for the output PDF file (optional)') | |
| parser.add_argument( | |
| '-q', '--quality', | |
| type=int, | |
| choices=[1, 2, 3, 4], | |
| default=2, | |
| help='Quality level (1-4, default=2, higher is better but slower)' | |
| ) | |
| args = parser.parse_args() | |
| input_path = Path(args.input_pdf) | |
| if args.output: | |
| output_path = Path(args.output) | |
| else: | |
| output_path = input_path.parent / f"{input_path.stem}_dark{input_path.suffix}" | |
| convert_to_dark_mode(str(input_path), str(output_path)) | |
| if __name__ == "__main__": | |
| main() |