offline-agency / image-puzzle
Split images into a grid of puzzle pieces with optional edge styles; export as PNG and JSON manifest.
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/offline-agency/image-puzzle
Requires
- php: ^8.4
- ext-gd: *
Requires (Dev)
- pestphp/pest: ^4.3
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^12.5
Suggests
- ext-pcntl: For parallel export (CLI)
This package is auto-updated.
Last update: 2026-02-02 12:14:23 UTC
README
Split images into a grid of puzzle pieces, optionally apply edge styles, and export each piece as PNG (or JPEG) plus a JSON manifest with metadata (rows/cols, piece dimensions, x/y offsets, filenames).
Requirements: PHP 8.4 or 8.5, ext-gd.
Installation
composer require offline-agency/image-puzzle
Quickstart
Recommended (three steps):
<?php require __DIR__ . '/vendor/autoload.php'; use ImagePuzzle\PuzzleGenerator; use ImagePuzzle\EdgeStyle\RoundedCornersStyle; $generator = new PuzzleGenerator(new RoundedCornersStyle(4)); $puzzle = $generator->generateFromFile('photo.jpg', 4, 6); $result = $puzzle->export('/path/to/output_dir'); echo "Exported " . count($result->getFiles()) . " files.\n"; echo "Manifest: " . $result->getManifestPath() . "\n";
One-shot (single call):
$result = PuzzleGenerator::generateAndExport('photo.jpg', '/path/to/output_dir', 4, 6, new RoundedCornersStyle(4));
Parallel export (when ext-pcntl is loaded and PHP is CLI) for large grids:
$exporter = new \ImagePuzzle\Exporter(); $result = $exporter->exportParallel('photo.jpg', '/path/to/output_dir', 4, 6, new \ImagePuzzle\ExportOptions(), 4, new RoundedCornersStyle(4));
Export and manifest
Each piece is saved as an image file (PNG by default). A manifest.json is written in the same directory with:
source– basename of the source imagerows,cols– grid sizesourceWidth,sourceHeight– original dimensionspieces– array of objects:row,col,x,y,width,height,filename
Example manifest snippet:
{
"source": "photo.jpg",
"rows": 4,
"cols": 6,
"sourceWidth": 1200,
"sourceHeight": 800,
"pieces": [
{
"row": 0,
"col": 0,
"x": 0,
"y": 0,
"width": 200,
"height": 200,
"filename": "piece_0_0.png"
}
]
}
Splitting rule
When the image size is not evenly divisible by rows/cols, remainder pixels are assigned to the last row and last column. For example, a 100×50 image with 3 columns gives column widths 33, 33, 34; with 2 rows gives row heights 25, 25.
Documentation
- docs/USAGE.md – Step-by-step usage
- docs/EXPORT.md – Export formats and options
- docs/EDGE_STYLES.md – Edge styles and config-driven style (JSON schema,
EdgeStyleFactory) - docs/EDGE_EXAMPLES.md – Example image for every edge type
- docs/SPLIT_STRATEGY.md – Customizing grid split strategy
JSON schemas for config and manifest: docs/schemas/ (edge-config.schema.json, puzzle-config.schema.json, piece.schema.json, manifest.schema.json). Config files are JSON-only; to use YAML or other formats, decode in your code (e.g. yaml_parse_file() if ext-yaml is available) and pass the resulting array to EdgeStyleFactory::fromArray($config).
Example script
php examples/generate.php input.jpg 4 6 output_dir php examples/generate.php input.jpg 4 6 output_dir --config=config/edge-config.json
Prints the manifest path and a short summary. Use --config=<path> to load edge style from a JSON config file. To use YAML, decode in your code and pass the array to EdgeStyleFactory::fromArray().
Image formats (GD)
Supported input formats: PNG, JPEG, GIF (as detected by GD). The exporter supports PNG and JPEG output.
Security
- When paths are user-supplied (e.g. from web input), resolve and restrict them to a base directory before calling the SDK (e.g.
realpath()and check prefix). - Export only writes files inside the given output directory;
filenamePatternandmanifestFilenamemust not contain path separators. - Very large grids (e.g. thousands of rows/cols) can use a lot of memory; consider reasonable limits.
Troubleshooting
- "cannot read from ..." – Ensure the file path is readable and the file is a valid image.
- "unsuported image type" – GD may not support that type; check
imagetypes()or use JPEG/PNG. - GD not found – Install ext-gd:
apt-get install php-gd, or enable it inphp.ini.
Extensions
Custom edge styles implement EdgeStyleInterface (see docs/EDGE_STYLES.md). Built-in styles include NoEdgeStyle, RoundedCornersStyle, and classic tab/socket styles (LineStyle, JigsawStyle, ArcStyle, HalfCircleStyle, SinusStyle). For per-side styles use CompositeEdgeStyle; for per-piece styles (e.g. by row/col or border vs inner) use ResolverEdgeStyle. You can create styles from JSON config with EdgeStyleFactory::fromArray() or EdgeStyleFactory::fromFile(). Third-party packages can provide additional styles as plugins.
Contributing
Please see CONTRIBUTING for details.
Security
If you discover any security-related issues, please email support@offlineagency.com instead of using the issue tracker.
Credits
Inspired by the original pear/Image_Puzzle (archived). This project is a from-scratch implementation with a modern API (PHP 8.4+, Composer, edge styles, export manifest).
About us
Offline Agency is a web design agency based in Padua, Italy. You'll find an overview of our projects on our website.
License
The MIT License (MIT). Please see License File for more information.