Dark mode works well until a page contains images. A black-on-white diagram may look better inverted. A photo usually will not.
A website can leave every image alone, invert every image, or tag them one by one. None of these options works well at scale.
Simple rules also fail. A white background does not mean an image is safe to invert. It may contain subtle colors, gradients, or a photo inside a diagram.
A small image classifier
I found the idea on Gwern’s idea list and built InvertOrNot to try it.
I fine-tuned EfficientNet-B0 on a custom set of labeled images. The API runs the exported ONNX model on a CPU, so deployment stays simple and does not need a GPU.
The API
The API accepts uploaded files, image URLs, or SHA-1 hashes. Each response includes the decision, the image hash, and any error.
Redis stores predictions by hash. For URL requests, it also remembers the URL’s last hash. Repeated requests can then skip the model, although a URL that changes its content can leave a stale mapping.
Learning from corrections
When a result is wrong, a user can submit a correction. The API adds the corrected label and image URL to a Redis queue. A separate script downloads those images into a dataset that I can use to fine-tune the next model.
This is not automatic retraining. It is a simple way to collect the real edge cases that matter.
Limits
Many cases are clear: diagrams often benefit from inversion, while photos do not. Mixed content and unusual colors are harder, and some images are genuinely ambiguous.
The model returns a binary decision using a 0.5 threshold. That makes the API easy to use, but it hides how close a prediction was to the boundary.
Deployment
The service uses FastAPI, Redis, and ONNX Runtime. It runs on one server without a GPU. CORS is open, so any website can call it.
The frontend is just as small: drop in an image or try an example to see the result.
A build-time integration pattern
A static site could call InvertOrNot at build time instead of classifying images in the browser. A build script would hash each image, check a local cache, and call the API only for new hashes.
Keeping the cache in version control makes later builds repeatable and avoids extra API calls. A manual override can handle the few decisions that do not fit the site’s design.
This site does not use that build flow today. It follows a simpler rule: CSS inverts article SVG diagrams in dark mode, while raster and Open Graph images stay unchanged.
Simple rules cannot cover every image. A small classifier gives me a useful default, and the correction queue gives me better data for the next version.
Try it at invertornot.com or read the code on GitHub.