Home (All Topics) → Technology → Software → AI-Created Software
The following AI-generated aka vibe-coded software. The software is specific to my needs and my system and may not work for you or your system. Support is limited, but if you report a bug I'll certainly look into it. All code is provided in a zip file for you to review should you choose.
A desktop tool for comparing two images, or two folders of images, pixel for pixel. You can view a pair with a draggable split divider, stack the two images and flip between them with a click, or show their pixel difference. It also has zoom, pan and a magnifying loupe for close inspection.
Built with Python, Tkinter and Pillow.
tkinterdnd2).
sudo apt install python3-tk.With no arguments, the app reopens the last paths you used. You can also pass paths on the command line:
# Compare two folders
python image-compare.py --left-file-or-folder-path ./before --right-file-or-folder-path ./after
# Compare two specific files (their names don't need to match)
python image-compare.py --left-file-or-folder-path a.png --right-file-or-folder-path b.png
# Match images in sub-folders too
python image-compare.py --left-file-or-folder-path ./before --right-file-or-folder-path ./after --recursive
| Option | Description |
|---|---|
--left-file-or-folder-path PATH |
File or folder for the left side. |
--right-file-or-folder-path PATH |
File or folder for the right side. |
--recursive |
Include images in sub-folders, matched by relative path. |
--settings-file-path PATH |
Settings file to load from and save to. If PATH is a folder, image_compare_settings.json is used inside it. |
Paths given on the command line take priority over the saved ones.
sub/dir/photo.png on the left pairs with sub/dir/photo.png on the right). Pairs are sorted by path, case-insensitively.Supported formats are .jpg, .jpeg, .png, .bmp, .gif, .tiff, .tif and .webp. Images are converted to RGB for display.
From top to bottom, the window contains:
3 / 20), and the right file, each with its native resolution. A red ⚠ note appears here when the two sizes differ.
| Action | Slider mode | Overlay mode |
|---|---|---|
| Left-click / drag on image | Move the divider | Flip between left and right |
| Mouse wheel | Zoom around the cursor | Zoom around the cursor |
| Middle-drag, right-drag or Shift + left-drag | Pan | Pan |
| Click a row in PAIRS | Open that pair | Open that pair |
| Key | Action |
|---|---|
← / → |
Previous / next pair (wraps around) |
+ or = |
Zoom in |
− |
Zoom out |
0 |
Fit to window |
1 |
100% (one screen pixel per image pixel) |
[ / ] |
Nudge the divider left / right by 1% (Slider mode) |
Space |
Flip between left and right (Overlay mode) |
Shortcuts are ignored while you’re typing in a path field.
When tkinterdnd2 is installed:
The pair list rescans automatically once both sides have a path.
Slider (the default) splits the view at the divider, with the left image on the left and the right image on the right. Each side’s folder or file name is shown in a caption in its top corner.
Overlay shows one full image at a time, in the same position and at the same zoom. Click anywhere on the image, or press Space, to flip to the other one. Only the caption for the image currently showing is displayed, in that side’s usual corner, and the COMPARE readout says showing LEFT or showing RIGHT. Switching back and forth quickly is often the fastest way to catch small shifts, crops or colour changes.
Difference takes precedence over both. When it is on, the view shows |left − right| for each pixel: black where the images are identical, brighter where they differ. Raise the × factor to multiply the difference and make subtle changes visible.
Difference needs both images on the same pixel grid, so it turns Match sizes on automatically if the resolutions differ.
The slider/overlay choice is remembered between sessions. Difference and Loupe always start off.
With Loupe on, a 360 × 360 px magnified inset follows the cursor. It appears just beside the outlined area it is sampling, so it never covers the spot you’re looking at. It moves to the other side of the cursor, or above/below it, near the edges of the view.
What the loupe shows depends on the mode:
A caption strip along the bottom of the loupe shows the magnification and the pixel coordinates of the cursor in the source image.
To change the loupe, edit these constants near the top of the script:
LOUPE_SIZE = 360 # on-screen size in px
LOUPE_ZOOM = 4.0 # magnification relative to the current view
LOUPE_GAP = 16 # gap between the sampled area and the loupe
When the two images in a pair have different resolutions, the app flags it in the info strip and marks the row with ⚠ in the PAIRS panel.
A mismatch usually means you’re comparing the wrong things, so the app points it out instead of silently hiding it.
At 200% and above, images are scaled with nearest-neighbour sampling so individual pixels stay crisp. Below that, Lanczos resampling is used to avoid aliasing. Only the visible region is resized, so zooming into very large images stays responsive.
The view resets to Fit whenever you open a new pair.
Zoom ranges from 2% to 6400%.
On Windows, the app declares itself DPI-aware, so 100% really means one screen pixel per image pixel, even when display scaling is set to 125% or 150%.
Settings are saved when you close the window to image_compare_settings.json in the same folder as the script. For a frozen build, the file goes next to the executable. Use --settings-file-path to put it somewhere else.
The saved settings are:
Settings files from older versions that used the path_left / path_right or folder_left / folder_right keys are still read.
If these files are present next to the script, they are used for the title bar and taskbar icon:
image-compare.ico
Resources/image-compare-icon-16.png
Resources/image-compare-icon-32.png
Resources/image-compare-icon-64.png
If they are missing, the app still runs with the default Tk icon and prints a one-line note to the console.


Leave a Reply