Skip to content

Instantly share code, notes, and snippets.

@anthonyryan1
Last active February 24, 2026 03:53
Show Gist options
  • Select an option

  • Save anthonyryan1/33b98f3caf50f7bee2bd09fbb37cc7fd to your computer and use it in GitHub Desktop.

Select an option

Save anthonyryan1/33b98f3caf50f7bee2bd09fbb37cc7fd to your computer and use it in GitHub Desktop.
GNOME/simple-scan ICC application through post-processing
#!/usr/bin/env python3
import os
import sys
import subprocess
import tempfile
import shutil
# Make sure you have imagemagick with lcms support
# Update the path to your ICC
# Save this somewhere, make it +x
# and point simple-scan post-processing at it
SCANNER_PROFILE = "/home/yourusername/path/to/your.icc"
sRGB_PROFILE = "/usr/share/color/icc/colord/sRGB.icc"
import gi
gi.require_version('Notify', '0.7')
from gi.repository import Notify
def send_notification(title, message, icon="scanner"):
if not Notify.is_initted():
Notify.init("Simple Scan Post-Processor")
# Create and show the notification
notification = Notify.Notification.new(title, message, icon)
notification.show()
# simple-scan passes at least 3 arguments:
# sys.argv[1] = mime-type
# sys.argv[2] = keep-origin
# sys.argv[3] = input-file
if len(sys.argv) < 4:
print("Error: Expected at least 3 arguments from simple-scan.", file=sys.stderr)
sys.exit(1)
mime_type = sys.argv[1]
keep_origin = sys.argv[2]
scan_file = sys.argv[3]
if not os.path.isfile(scan_file):
print(f"Error: File '{scan_file}' does not exist.", file=sys.stderr)
sys.exit(1)
# Only process PNG files
if mime_type != 'image/png' and not scan_file.lower().endswith('.png'):
print(f"Skipping '{scan_file}': Not a PNG file (MIME: {mime_type}).")
sys.exit(0)
# Verify profiles exist
for profile in [SCANNER_PROFILE, sRGB_PROFILE]:
if not os.path.isfile(profile):
error_msg = f"ICC profile not found:\n{profile}"
print(error_msg, file=sys.stderr)
send_notification("Scan Processing Failed", error_msg, "dialog-error")
sys.exit(1)
# Create a secure temporary file for the ImageMagick output
fd, temp_file = tempfile.mkstemp(suffix='.png', prefix='scan_hook_')
os.close(fd)
try:
# Construct the ImageMagick command
cmd = [
"magick",
scan_file,
"-profile", SCANNER_PROFILE,
"-profile", sRGB_PROFILE,
temp_file
]
print(f"Applying color profiles to '{scan_file}'...")
# Run the command
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
# Safely replace the original file
shutil.move(temp_file, scan_file)
filename = os.path.basename(scan_file)
print(f"Successfully processed and replaced '{scan_file}'.")
# Send success notification
send_notification(
"Scan Processed",
f"Color profiles applied to {filename}",
"image-x-generic"
)
else:
print(f"ImageMagick failed with error:\n{result.stderr}", file=sys.stderr)
os.remove(temp_file)
# Send failure notification
send_notification(
"Scan Processing Failed",
"ImageMagick encountered an error.",
"dialog-error"
)
sys.exit(1)
except Exception as e:
print(f"An unexpected error occurred: {e}", file=sys.stderr)
if os.path.exists(temp_file):
os.remove(temp_file)
send_notification(
"Scan Processing Error",
str(e),
"dialog-error"
)
sys.exit(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment