A browser-based tool for creating professional logo banner graphics from a set of mixed-aspect-ratio logos. Upload your logo files, set your canvas size, and the app automatically arranges them into a clean, evenly spaced, canvas-filling banner — all client-side, no uploads, no backend.
Live demo: https://logo-banner-generator-production.up.railway.app
Given a canvas size and a collection of PNG or SVG logos, the generator:
- Arranges logos into rows so that every logo shares the same height
- Fills the canvas as fully as possible by finding the row count and grouping that maximises total logo area
- Distributes gaps evenly within each row, expanding them to use all available horizontal space
- Keeps logos in filename order so your arrangement is predictable and reproducible
It handles the common real-world problem of combining logos with wildly different aspect ratios (tall-and-narrow icons, wide-and-short wordmarks, square badges) into a single cohesive banner without manually resizing each one.
- Auto-optimised row packing — tries every row count from 1 to N and selects the one with the highest canvas coverage score
- Row and column overrides — lock in a specific number of rows, or cap the maximum logos per row
- Canvas margins — set independent horizontal and vertical insets so logos never touch the edge
- Gap uniformity control — set a maximum allowed gap difference (%) between rows; the engine shrinks outlier rows (up to a configurable limit) to bring spacing in line
- Per-logo scale — click any logo in the preview to scale it independently (10–200%), shrinking both width and height proportionally with vertical centring
| Format | Notes |
|---|---|
| PNG | Full-resolution raster, respects background colour |
| SVG | Vector output; SVG logos are inlined (fully scalable), raster logos base64-embedded |
| PSD / PSB | Layered Photoshop file — each logo on its own named, positioned layer. Automatically uses PSB (Large Document) for canvases over 30 000 px. Optional Photoshop guides for layout edges, margins, and bleed |
- PNG and SVG files with transparency
- SVG dimensions read from
viewBoxorwidth/heightattributes, with<img>fallback - Files sorted by filename for a stable, repeatable layout
npm install
npm run devOpen the local URL printed in the terminal.
npm run build
npm run preview- Enter the target canvas width and height in pixels
- Set margins (left/right, top/bottom) if you need padding around the logo area
- Set a minimum gap — gaps expand beyond this to fill available space
- Optionally adjust max gap difference % and max shrink % to control how uniform the spacing looks across rows
- Drag and drop (or browse for) your PNG/SVG logo files
- Click any logo in the preview to adjust its individual scale
- Use Layout overrides to force a specific row or column count if needed
- Export as PNG, SVG, or PSD
For each candidate row count k (1 to min(N, 40)), logos are partitioned into k contiguous groups using a dynamic programming min-max partition: find the split that minimises the largest per-row aspect-ratio sum. Minimising the heaviest row's aspect sum maximises the achievable logo height H for that k.
H is then bounded by both the tightest row's width constraint and the canvas height constraint. Each candidate is scored by total logo area / canvas area and the highest-scoring k is selected.
A second gap uniformity pass computes the mean horizontal gap across all rows. Any row whose gap exceeds the allowed tolerance is corrected by scaling its logos down (up to maxShrink) so its gap approaches the mean.
Per-logo user scales are applied after this pass, uniformly shrinking both the width and height of individual logos while centering them vertically in their row band.
See src/lib/layoutEngine.js for the full implementation.
- React + Vite
- Tailwind CSS
- ag-psd for PSD/PSB export
src/
├── App.jsx # state management, layout wiring
├── components/
│ ├── ControlsPanel.jsx # all user inputs
│ ├── BannerPreview.jsx # interactive live preview, per-logo scale UI
│ └── ExportButtons.jsx # PNG / SVG / PSD export with guide options
└── lib/
├── layoutEngine.js # row-packing algorithm
├── imageUtils.js # file loading, SVG dimension parsing
└── exportUtils.js # PNG, SVG, PSD serialisation
MIT