Disclaimer: This is an AI-generated project. I've had this idea lingering in my mind for a while, but I never actually reviewed the code itself.
imagegen is a Go CLI that builds a photo mosaic from a source image and a directory of tile images.
It splits the main image into a grid, computes the mean RGB color of each cell, finds a close tile image for that cell, crop-fits the tile to a uniform cell size, and renders a final collage image.
- Supports PNG and JPEG inputs
- Scans tile images recursively from a directory
- Caches tile mean colors in memory for faster matching
- Uses parallel indexing, matching, and render preparation
- Shows a progress bar during CLI runs
- Supports optional controlled randomization to reduce visible repetition
- Go 1.26+
./bin/imagegen -main ./imgsrc/real_dataset/people_111.jpg \
-grid-height 72 -grid-width 108 -scale 10 -tiles ./imgsrc/real_dataset \
-output out.jpg -randomness 0.5
make buildThe binary is written to:
./bin/imagegenmake fmt
make lint
make test
make build./bin/imagegen \
--main ./main.jpg \
--tiles ./imgsrc \
--grid-width 80 \
--grid-height 60 \
--scale 4 \
--output ./mosaic.png| Flag | Required | Description |
|---|---|---|
--main |
yes | Path to the main source image |
--tiles |
yes | Directory containing tile images; scanned recursively |
--grid-width |
yes | Number of columns in the source grid |
--grid-height |
yes | Number of rows in the source grid |
--scale |
yes | Output size multiplier relative to the source image |
--output |
yes | Output file path; supports .png, .jpg, .jpeg |
--randomness |
no | Variation amount from 0.0 to 1.0; default 0.0 |
--seed |
no | Seed for reproducible randomized matching |
With --randomness 0, matching is deterministic:
- Compute the mean RGB color of each source cell.
- Compute the mean RGB color of each tile image.
- Pick the single closest tile by RGB distance.
When --randomness is greater than 0:
- The matcher keeps a small pool of near-best candidates.
- It chooses from that pool randomly, with a bias toward the better color matches.
- If you pass
--seed, the result is reproducible.
This helps reduce repeating patterns when the tile set is small or the source image contains many similar regions.
The output image size is derived from:
- the source image size
- the grid dimensions
- the scale multiplier
Each grid cell in the final output has the same size. Tile images are center-cropped and resized to fit that cell.
- Only PNG and JPEG are supported.
- Tile reuse is currently unlimited.
- Randomization changes tile choice, not output dimensions.
- The progress bar is written to
stderr.