image-grid-combine
Combine several images into one grid image, with Pillow.
Point it at a handful of photos and it lays them out on a single canvas: square-ish
grid by default, equal cells, cover-cropped so nothing is distorted. The layout
maths is plain Python with no Pillow import, so you can reuse the geometry on its
own if you already have your own drawing code.
pip install image-grid-combine
Command line
image-grid-combine grid.png one.jpg two.jpg three.jpg four.jpg
Four images become a 2x2 grid. Add a gutter and a margin:
image-grid-combine grid.png *.jpg --columns 3 --gap 12 --padding 24
Transparent background, cells pinned to 512x512, letterboxed instead of cropped:
image-grid-combine grid.png *.png --cell-size 512 --fit contain --background none
Run image-grid-combine --help for the full list.
| Option | Default | Meaning |
|---|---|---|
--columns |
auto | Cells per row. Auto keeps the grid as square as the count allows. |
--gap |
0 |
Pixels between neighbouring cells. |
--padding |
0 |
Pixels around the outside of the grid. |
--background |
white |
#rgb, #rrggbb, #rrggbbaa, r,g,b[,a], a colour name, or none. |
--fit |
cover |
cover crops to fill, contain letterboxes, stretch distorts. |
--cell-size |
auto | 512 or 512x384. Auto uses the largest source, capped by --max-width. |
--max-width |
2048 |
Width cap when the cell size is auto. |
--max-height |
none | Optional height cap when the cell size is auto. |
Library
from image_grid_combine import combine
grid = combine(["a.jpg", "b.jpg", "c.jpg", "d.jpg"], columns=2, gap=12)
grid.save("grid.png")
Sources can be paths, bytes, binary file objects, or PIL.Image.Image
instances — handy if the images came off the network or out of a database and you
would rather not round-trip them through disk. The result is always an RGBA
image; nothing you pass in is modified.
from io import BytesIO
from image_grid_combine import combine, combine_to_file
grid = combine([open("a.jpg", "rb"), BytesIO(response.content)], fit="contain")
combine_to_file("grid.jpg", ["a.jpg", "b.jpg"], gap=8) # JPEG flattens onto white
combine_to_file picks the format from the file extension. JPEG has no alpha
channel, so the grid is flattened onto the background before saving.
Layout on its own
If you are drawing somewhere other than a Pillow canvas — a PDF, a reportlab document, a matplotlib figure — the geometry is importable without Pillow:
from image_grid_combine.layout import auto_cell_size, compute_grid_layout, fit_rect
cell_w, cell_h, columns = auto_cell_size([(1600, 900), (900, 1600)], gap=12)
for cell in compute_grid_layout(2, columns, cell_w, cell_h, gap=12):
rect = fit_rect(1600, 900, cell.width, cell.height, "cover")
print(cell.x, cell.y, rect.sx, rect.sy, rect.sw, rect.sh)
fit_rect returns a FitResult naming both rectangles: the crop to take from the
source (sx, sy, sw, sh) and the box to draw it into (dx, dy, dw,
dh). Under cover the destination is the whole cell and the source is cropped;
under contain it is the other way round.
Notes
- Cell sizes are equal across the grid, so mixing a panorama with a portrait
gives you two cropped images rather than a ragged layout.
--fit containtrades the crop for letterboxing. - Cropping and scaling round to whole pixels, so the last row of a partial grid can differ by a pixel from the rows above it. That is deliberate — sub-pixel placement blurs edges.
- Works on Python 3.8+. The only dependency is Pillow.
Related
- ai image combiner — a browser-based AI image combiner for when you would rather not write code: drop in two or more photos and merge them with AI blending, no install and no signup.
License
MIT
Metadata
Release files for image-grid-combine 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| image_grid_combine-1.0.0.tar.gz | 15.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| image_grid_combine-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.4 kB
Release files / image_grid_combine-1.0.0.tar.gz
| Download URL | image_grid_combine-1.0.0.tar.gz |
|---|---|
| Size | 15.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e3c1dc51c1ec1418310d6e5ea378c3df50b772da9d409a8fdf7ac5915627d7f0
|
|
BLAKE2b-256 checksum How to use checksums |
99be81777391e7413885cf4fb8deaa4f23fe6f46e55a234bc8a2b9fa744dc43e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Release files / image_grid_combine-1.0.0-py3-none-any.whl
| Download URL | image_grid_combine-1.0.0-py3-none-any.whl |
|---|---|
| Size | 11.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c7f56841d1d9cd8b4eb2c7e429b7d90dcaf689befe40d80c0fe688eb1a46b51b
|
|
BLAKE2b-256 checksum How to use checksums |
b83d7561b341471393041c28499b2cc603e3151a1e0656f868dd65b071edfb4d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|