Image Splitter — Zig source
Split an image into an even grid of tiles — rows × columns with a live cut-line preview and per-tile or bulk PNG download. Runs entirely in your browser.
This is the Zig implementation — the same logic the interactive tool runs, in a shareable, citable form.
// Image splitter — tile geometry — Zig port of the image-splitter tool.
const std = @import("std");
/// One cut of the grid: the source rectangle that becomes a tile. In the
/// browser tool this rect is drawImage'd into its own canvas and encoded
/// to PNG; the geometry here is the deterministic part of that pipeline.
const TileRect = struct {
x: i32,
y: i32,
width: i32,
height: i32,
fn format(
self: TileRect,
comptime _: []const u8,
_: std.fmt.FormatOptions,
writer: anytype,
) !void {
try writer.print("src=({d}, {d}) {d}x{d}", .{
self.x, self.y, self.width, self.height,
});
}
};
/// Split a width x height image into rows x cols tiles, row-major.
/// Mirrors splitToTiles in typescript.ts: tileW = floor(width / cols),
/// tileH = floor(height / rows) — Zig integer division truncates toward
/// zero, which IS Math.floor for positives, so a 1024px width over 3 cols
/// yields 341px tiles and the last 1px column is dropped, exactly like the
/// TS. Caller owns the returned slice.
fn splitTiles(
allocator: std.mem.Allocator,
width: i32,
height: i32,
rows: i32,
cols: i32,
) ![]TileRect {
const tile_w = @divTrunc(width, cols);
const tile_h = @divTrunc(height, rows);
var tiles = std.ArrayList(TileRect).init(allocator);
errdefer tiles.deinit();
var row: i32 = 0;
while (row < rows) : (row += 1) {
var col: i32 = 0;
while (col < cols) : (col += 1) {
try tiles.append(.{
.x = col * tile_w,
.y = row * tile_h,
.width = tile_w,
.height = tile_h,
});
}
}
return tiles.toOwnedSlice();
}
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
// 1024x768 image, 2 rows x 3 cols -> six 341x384 tiles.
const tiles = try splitTiles(arena.allocator(), 1024, 768, 2, 3);
for (tiles) |tile| {
try std.io.getStdOut().writer().print("{f}\n", .{tile});
}
}
Also available in 8 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →