DEV Community

fatik07
fatik07

Posted on

I let Gemma 4 name 198 screenshots I was never going to rename

Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission 🦥

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady

What I Built

My screenshot folder has 226 files in it. 198 of them are called something like this:

Screenshot from 2022-11-15 10-01-34.png
Enter fullscreen mode Exit fullscreen mode

193 are from my old Ubuntu laptop, moved over to my Mac and never touched again. Every time I need "that Laravel error from last year", I open them one by one. I have never renamed a screenshot by hand, and I'm not going to start now.

So I built sloth-shots, a small command-line tool that looks at each screenshot with an open-weight vision model (Gemma 4) and renames it after what's actually in it:

Screenshot from 2022-11-15 10-01-34.png  ->  2022-11-15_laravel-postgresql-role-does-not-exist.png
Screenshot from 2022-12-14 10-33-31.png  ->  2022-12-14_php-undefined-type-pdf-error.png
Screenshot from 2022-03-29 10-09-20.png  ->  2022-03-29_jsfiddle-javascript-matrix-code-snippet.png
Enter fullscreen mode Exit fullscreen mode

The date stays at the front, so the folder still sorts by time. The rest of the name is something Spotlight can actually find.

It has two modes:

  • tidy renames the backlog you already have.
  • watch stays running in the background. Take a screenshot, and about a second later it has a real name. You don't do anything.

Demo

This is a real dry run on 20 copies of screenshots from my folder (Gemma 4 31B through OpenRouter). The whole run took 22 seconds:

$ sloth-shots tidy ~/demo
Dry run (nothing is renamed; add --apply): 20 screenshot(s)

Screenshot from 2022-08-25 09-20-51.png
  ~> 2022-08-25_vscode-file-explorer-project-structure.png  (1.3s)
Screenshot from 2022-09-13 14-34-26.png
  ~> 2022-09-13_comparison-shared-vs-cloud-hosting.png  (1.2s)
Screenshot from 2022-09-21 14-20-35.png
  ~> 2022-09-21_dicoding-computer-knowledge-quiz.png  (0.9s)
Screenshot from 2022-10-06 10-52-21.png
  ~> 2022-10-06_vscode-css-flexbox-container-settings.png  (0.9s)
Screenshot from 2022-11-15 10-01-34.png
  ~> 2022-11-15_laravel-postgresql-role-does-not-exist.png  (0.9s)
Screenshot from 2022-12-05 09-42-39.png
  ~> 2022-12-05_petanikode-programming-loop-flowchart.png  (0.9s)
Screenshot from 2022-12-14 10-33-31.png
  ~> 2022-12-14_php-undefined-type-pdf-error.png  (2.7s)
Screenshot from 2023-02-04 11-51-35.png
  ~> 2023-02-04_phpmyadmin-rajaongkir-province-table.png  (0.9s)
Screenshot from 2023-05-08 14-31-20.png
  ~> 2023-05-08_vscode-json-api-response-data.png  (1.0s)
...
Enter fullscreen mode Exit fullscreen mode

You may notice there are no screenshots in this post, only filenames. That's on purpose. When I checked the results, the Laravel error contained a company database hostname, its IP address and an employee ID, and the JSFiddle one was taken during a Google Meet call with other people's names and faces in it. Screenshots are full of things you'd never post. That's also why I care about the model being open, more on that below.

I checked several of the names against the actual images. Most were spot on. One was wrong: terminal-update-alternatives-command is really a Telegram chat preview that happens to show a sudo update-alternatives command. That's a reasonable mistake, and the name is still more findable than Screenshot 2023-06-17 at 14.13.24.png.

Code

sloth-shots 🦥

Your screenshot folder is full of files called Screenshot 2023-06-17 at 14.11.12.png. You will never find the one you need.

sloth-shots looks at each screenshot with an open-weight vision model (Gemma 4) and renames it after what's in it. Real output from my own screenshot folder:

Screenshot from 2022-11-15 10-01-34.png  ->  2022-11-15_laravel-postgresql-role-does-not-exist.png
Screenshot from 2022-12-14 10-33-31.png  ->  2022-12-14_php-undefined-type-pdf-error.png
Screenshot from 2022-03-29 10-09-20.png  ->  2022-03-29_jsfiddle-javascript-matrix-code-snippet.png

Leave watch running and you never think about it again. Take a screenshot and about a second later it has a name you can search for in Spotlight.

Setup

  1. Get an API key at https://openrouter.ai/keys. A few dollars of credit goes a long way: each screenshot costs about $0.00003.

  2. Export it:

    export OPENROUTER_API_KEY=sk-or-...
    Enter fullscreen mode Exit fullscreen mode
  3. Run the tool. It has no dependencies beyond Python 3.10+:

    uvx --from . sloth-shots --help
    # or simply
    python3 sloth_shots.py --help
    Enter fullscreen mode Exit fullscreen mode

Usage

If you don't pass a folder, sloth-shots…




It's one Python file with no third-party dependencies:

export OPENROUTER_API_KEY=sk-or-...
python3 sloth_shots.py tidy --limit 5          # dry run, renames nothing
python3 sloth_shots.py tidy --limit 5 --apply  # apply (reuses the dry-run answers)
python3 sloth_shots.py watch                   # rename new screenshots as you take them
python3 sloth_shots.py stats                   # how much effort you've saved
python3 sloth_shots.py undo                    # put every original name back
Enter fullscreen mode Exit fullscreen mode

How I Built It

The pipeline for each screenshot is short:

  1. Find it. Only image files whose names start with Screenshot or Screen Shot are touched. A renamed file no longer matches, so nothing gets processed twice. Other locales work with --prefix.
  2. Shrink it. macOS's built-in sips downscales the image to 1024px before upload. A 965 KB retina PNG becomes about 80 KB. If the original is already smaller, it sends the original.
  3. Ask Gemma. The image goes to Gemma 4 with a short prompt: 3 to 6 words, lowercase, hyphenated, name the app first, be specific ("vscode-python-import-error" beats "code-editor").
  4. Clean the answer. Models sometimes get chatty ("Sure! Here's a name: …"), so the tool pulls the hyphenated part out of the reply. If there's nothing usable, the file is skipped rather than renamed to junk.
  5. Rename safely. It never overwrites a file (collisions get -2), logs every rename to a .jsonl file so undo works, and tidy is a dry run until you add --apply. Dry-run answers are cached, so applying them doesn't call the model again.

watch is a plain polling loop: it checks the folder every 2 seconds and waits until a file's size stops changing, because macOS writes screenshots in steps.

The hardest part wasn't the code, it was getting a response at all. I started on the free Gemma 4 endpoints, and this week they were swamped. Every request came back 429: temporarily rate-limited upstream, and the few that got through took 70 to 90 seconds. So the tool now tries a list of models in order: Gemma 4 31B, then Gemma 4 26B-A4B, then the free tier. If one is busy or out of credit, it moves to the next instead of sitting in a retry loop.

Why Does Open Innovation Matter?

Gemma 4's weights are public, and that changed how this project turned out in two ways.

It made it almost free. Because anyone can host the weights, about a dozen providers serve Gemma 4 on OpenRouter and compete on price. Naming my 20 test screenshots cost $0.0008. The full backlog of 198 comes to under one cent. When the free pool was overloaded, I could simply switch to a paid provider running the exact same model. With a closed model, I'd have one vendor and one price.

It means the model is mine to keep. The model naming my screenshots today will behave the same way next year. Nobody can deprecate it or quietly retrain it, which matters for a tool whose whole job is to be consistent across thousands of files.

And there's the privacy problem I hit in the demo: my screenshots contain hostnames, IDs and other people's faces. Right now they go through OpenRouter. Because the weights are open, the same model can also run fully offline on my own laptop, and a local backend is the next thing I want to add. That's only an option because the model is open.

The Lazy Payoff

  • 198 screenshots in my folder with no real name.
  • Renaming one by hand means opening it, looking at it, thinking of a name and typing it. Call it 20 seconds. That's about 66 minutes I was never going to spend.
  • sloth-shots did 20 of them in 22 seconds for $0.0008, and in watch mode it takes zero effort from me from now on.

The best part is that I don't have to remember to run it. That's the whole point.

Prize Categories

  • Best Use of Gemma: Gemma 4 (31B and 26B-A4B) is the only model the project uses. It does all the vision work.

Top comments (0)