Okay, let's break this down.
Yes, it is possible to achieve a color inversion effect in Ghostscript, similar to the invert(100%) part of your CSS filter. Replicating the hue-rotate(180deg) part exactly is significantly more complex within Ghostscript's standard processing model, but the simple inversion often gets you 90% of the way to a usable "dark mode".
The core idea is to use PostScript's transfer functions. These functions modify color component values just before they are rendered. To invert a color component c (where c is between 0 and 1), the function is simply 1 - c.
We need to apply this function to all relevant color spaces commonly found in PDFs: DeviceGray, DeviceRGB, and DeviceCMYK.
Here is the Ghostscript command you can use in a Bash shell script:
#!/bin/bash
# Input PDF file
input_pdf="input.pdf"
# Output PDF file (dark mode)
output_pdf="output_dark.pdf"
# Check if input file exists
if [[ ! -f "$input_pdf" ]]; then
echo "Error: Input file '$input_pdf' not found."
exit 1
fi
echo "Applying color inversion to '$input_pdf' -> '$output_pdf'..."
# Ghostscript command
gs \
-o "$output_pdf" \
-sDEVICE=pdfwrite \
-dPDFSETTINGS=/default \
-dNOPAUSE \
-dBATCH \
-c '<</TransferFunction {1 exch sub} /TransferFunctionRGB [ {1 exch sub} {1 exch sub} {1 exch sub} ] /TransferFunctionCMYK [ {1 exch sub} {1 exch sub} {1 exch sub} {1 exch sub} ]>> setpagedevice' \
-f "$input_pdf"
# Check if Ghostscript was successful
if [[ $? -eq 0 ]]; then
echo "Successfully created '$output_pdf'."
else
echo "Error during Ghostscript processing."
# Optional: remove potentially incomplete output file
# rm -f "$output_pdf"
exit 1
fi
exit 0Explanation:
#!/bin/bash: Shebang line for Bash scripts.input_pdf="...",output_pdf="...": Variables for filenames.if [[ ! -f ... ]]: Basic check to ensure the input file exists.gs: The Ghostscript command.-o "$output_pdf": Specifies the output file name.-sDEVICE=pdfwrite: Tells Ghostscript to output a PDF file. This device re-interprets and re-generates the PDF.-dPDFSETTINGS=/default: A general preset for compatibility and size. You could try/printeror/prepressfor potentially higher quality if needed.-dNOPAUSE -dBATCH: Essential for running Ghostscript non-interactively in a script.-c '...': Executes the following PostScript code string.<< ... >> setpagedevice: This is the PostScript syntax for setting page device parameters. We are modifying how colors are handled for the entire page./TransferFunction {1 exch sub}: Sets the transfer function forDeviceGraycolor space.{1 exch sub}is PostScript code: it takes the input gray value (which is left on the stack), pushes1, swaps them (exch), and subtracts (sub), effectively calculating1 - input_gray./TransferFunctionRGB [ {1 exch sub} {1 exch sub} {1 exch sub} ]: Sets the transfer functions forDeviceRGB. It takes an array of three procedures, one for Red, one for Green, one for Blue. We use the same inversion logic for all three./TransferFunctionCMYK [ {1 exch sub} {1 exch sub} {1 exch sub} {1 exch sub} ]: Sets the transfer functions forDeviceCMYK, applying the inversion to Cyan, Magenta, Yellow, and Black components.
-f "$input_pdf": Specifies the input PDF file. Crucially, the-ccode runs before Ghostscript starts processing the pages from this file, setting up the color inversion environment.if [[ $? -eq 0 ]]: Checks the exit status of thegscommand to report success or failure.
Limitations & Considerations:
- Hue Rotation: This command only performs the
invert(100%). Replicatinghue-rotate(180deg)would require intercepting and transforming every color specification (e.g., viasetrgbcolor,setcmykcolor, image data, etc.) through a color space conversion (like RGB -> HSL -> modify H -> HSL -> RGB), which is extremely complex and fragile to implement robustly in Ghostscript for arbitrary PDFs. The simple inversion is usually sufficient for a dark mode effect. - Color Spaces: This handles the most common device color spaces. PDFs using ICC profiles, Indexed colors, or Separation colors might behave differently or not be inverted correctly.
- Transparency & Blend Modes: Complex transparency and blend modes might produce unexpected results after inversion.
- Images vs. Vectors: The inversion applies universally, affecting both vector elements (text, lines) and raster images.
- Quality/Fidelity:
pdfwritere-generates the PDF. While generally good, it's not guaranteed to be a 100% perfect replica of the original structure, only the visual appearance (as modified by the transfer functions).
Save the script (e.g., pdf_darkmode.sh), make it executable (chmod +x pdf_darkmode.sh), place your input PDF as input.pdf in the same directory, and run it (./pdf_darkmode.sh). It will create output_dark.pdf.