SkillAgentSearch skills...

Cullergrader

Cullergrader is a simple Java GUI made for photographers that groups and exports images based on perceptual similarity (and timestamps), allowing users to select the best shots from each set of similar, consecutively taken photos.

Install / Use

/learn @PenguinPush/Cullergrader

README

Cullergrader

Cullergrader is a simple Java GUI made for photographers that groups and exports images based on <a href="https://en.wikipedia.org/wiki/Perceptual_hashing" target="_blank">perceptual similarity</a> (and timestamps), allowing users to select the best shots from each set of similar, consecutively taken photos.

Like many photographers, I have the habit of taking the same shot multiple times and selecting the best one to keep. However, when going through thousands of photos, this process of culling images is time-consuming, and tools such as <a href="https://github.com/qarmin/czkawka" target="_blank">Czkawka</a> (a large inspiration for this project) can detect a few very similar images, but isn't sensitive enough to group somewhat similar bursts.

Cullergrader is named for being a tool that culls and grades* photos. Please note that it doesn't actually colour grade photos.

<sub>* grading photos has yet to be implemented...</sub>

<div style="display: flex; justify-content: center; align-items: center; gap: 20px;"> <img src="images/exampleA.JPG" alt="DSC07442.JPG" width="300"/> <img src="images/exampleB.JPG" alt="DSC07443.JPG" width="300"/> </div> <p align="left">For example: Cullergrader would mark these two images as "similar" (at similarity threshold >= 37%)</p>

Table of Contents

  1. Features
  2. Installation
    1. Prebuilt Executable
    2. Compiling from Source
  3. How to Use
    1. Open a Folder of Images
    2. Calibrate Grouping Settings
    3. View Photos and Select Best Takes
    4. Export Your Best Takes
  4. Config
    1. Default Config
    2. Config Settings Explained
  5. Contributing
  6. License

Features

  • 100% free and open-source!
  • Configurable options for calibrating your perceptual hash
    • Hash similarity
    • Timestamp difference
  • Exports the best takes to any folder on your computer
  • Runs on Windows, Mac, Linux, and anything else that supports Java GUIs
  • Blazingly-fast thanks to configurable multithreading support
  • Caches images -- future scans should be incredibly fast!
  • Extra information about images available on hover
  • Runs completely offline, and never connects to the internet
  • Logs information to .txt files
  • Light/Dark themes from FlatLaf
  • Configurable:
    • Multithreading
    • Hashing settings
    • Cache options
    • Grouping settings
    • Dark theme

images/group_viewer.png

Installation

Prebuilt Executable

  1. Cullergrader requires a Java 8 JRE or newer to run
  2. A prebuilt executable .jar with all libraries bundled is available for download at GitHub Releases
  3. Extract the .zip file to any folder and run cullergrader-<version>.jar file to begin using Cullergrader

Note:

  • If you want to view logs in console, please use run.bat or run.sh depending on your operating system
  • Using console is highly recommended for large batches of images (or on slow drives), as there is no other way to monitor slow hashing progress!

Compiling from Source

  1. Ensure you have the following installed:
    • Java Development Kit (JDK) 8 or newer
    • Apache Maven
  2. Clone the repository with:
    git clone https://github.com/PenguinPush/cullergrader.git
    cd cullergrader
    
  3. Build the project with the following command:
    mvn clean install
    
  4. Extract the generated cullergrader-version.zip and run as described above

How to Use

1. Open a Folder of Images

Folders can be opened from File > Open Folder or with Ctrl + O. The first time images are computed, it may take a few minutes (but often less) to hash the images, depending on image count and disk speed. Hashes are cached for future use in cache.json, so as long as this file stays intact, future computations of the same images will be nearly instant.

images/open_folder.png

2. Calibrate Grouping Settings

Although the default settings are designed to work fine out of the box, depending on many factors in your photo, and your style of photography, manual calibration is often recommended. By adjusting the timestamp and similarity thresholds and hitting Reload Groups, you can adjust how your images are grouped until the grouping behaves as expected.

  • Timestamp Threshold is the amount of seconds between two photos before it counts it as no longer a part of the same photo group, and creates a new group
  • Similarity Threshold is the percentage of similarity between the hash of two photos. A higher threshold means more tolerance for less similar photos to be in the same group.

images/grouping_settings.png

3. View Photos and Select Best Takes

By clicking on a photo, users can access the Photo Viewer, bringing up all individual photos in a group, with the best take marked by a star (which by default is the first image in group). By navigating using either mouse or arrow keys (left and right to move between photos, up and down to move between groups) to a photo, they can use the spacebar or Controls > Set Best Take to change a photo to the best take.

images/photo_viewer.png

Tip: by hovering on a photo in the photo viewer, you can view its name, seconds between the last photo, and similarity % to the last photo. Use this information to help you calibrate the grouper.

images/photo_info.png

4. Export Your Best Takes

Best takes can be exported to a folder using File > Export Best Takes or with Ctrl + S. After choosing an export folder, the selected best takes will begin copying to that folder!

images/export_to.png

Config

Default Config

{
    "DARK_THEME": true,
    "CACHE_FILE": "hashes.json",
    "LOG_DIRECTORY": "logs",
    "DEFAULT_FOLDER_PATH": "",
    "HASHING_ENABLED": true,
    "EXECUTOR_TIMEOUT_MINUTES": 60,
    "MAX_THREADS_RATIO": 2,
    "HASHED_WIDTH": 8,
    "HASHED_HEIGHT": 8,
    "TIME_THRESHOLD_SECONDS": 15,
    "SIMILARITY_THRESHOLD_PERCENT": 45
}

Config Settings Explained

| Setting | Description | Variable Type | |--------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------| | DARK_THEME | Toggles the dark and light FlatLaf themes. On by default (obviously) | boolean | | CACHE_FILE | The name of the file used to store hash caches. Passed as a pathname in a File constructor | String | | LOG_DIRECTORY | The name of the folder used to store logs. Passed as a pathname in a File constructor | String | | DEFAULT_FOLDER_PATH | The default folder opened when importing images. Passed as a pathname in a File constructor. When empty, uses the systems user.home property | String | | HASHING_ENABLED | Whether or not hashing is used in grouping photos | boolean | | EXECUTOR_TIMEOUT_MINUTES | The amount of time, in minutes, before the hash manager times out and stops hashing photos | int | | MAX_THREADS_RATIO | The fraction of CPU threads the hasher is allowed to multithread. 2 means half your threads, 3 means a third, etc. | int | | HASHED_WIDTH | The width that images are computed at before hashing, higher values mean more accurate similarity checks at the cost of performance | int | | HASHED_HEIGHT | The height that images are computed at before hashing, higher values mean more accurate similarity checks at the cost of performance | int | | TIME_THRESHOLD_SECONDS | The default amount of seconds between photos (from the timestamp) before they're counted as a new group. Editable in-app, but will not change the default stored here | float | | SIMILARITY_THRESHOLD_PERCENT | The default similarit

Related Skills

View on GitHub
GitHub Stars9
CategoryDevelopment
Updated23d ago
Forks2

Languages

Java

Security Score

90/100

Audited on Mar 11, 2026

No findings