Industrial-grade 2D rectangle bin packing and texture atlas layout engine in pure MoonBit.
moon add zmjknn/moon_binpack///|
import {
"zmjknn/moon_binpack",
}let items = [
@moon_binpack.Size::new(128, 64),
@moon_binpack.Size::new(64, 128),
@moon_binpack.Size::new(96, 96),
@moon_binpack.Size::new(48, 48),
]
let (best_res, winning_algo) = @moon_binpack.best_pack(
items,
max_width=512,
max_height=512,
)
println("Winning Heuristic: " + winning_algo)
println("Occupancy: " + (best_res.stats.occupancy * 100.0).to_string() + "%")let img1 = @moon_binpack.PixelBuffer::new(48, 32, color=@moon_binpack.Rgba::from_hex(0xFF4444))
let img2 = @moon_binpack.PixelBuffer::new(32, 48, color=@moon_binpack.Rgba::from_hex(0x44FF44))
let items = [
@moon_binpack.ImageItem::new(1, img1),
@moon_binpack.ImageItem::new(2, img2),
]
// Automatically benchmarks layout and bakes with 1-pixel outer edge extrusion
let baker = @moon_binpack.AtlasBaker::new(extrude_margin=1)
let (baked_pages, winner) = baker.bake_best(items)
let page0 = baked_pages[0]
// Pure MoonBit zero-dependency image encoding
let bmp_bytes = page0.image.to_bmp_bytes()
let tga_bytes = page0.image.to_tga_bytes()
// Half-texel UV coordinates for WebGPU / DirectX shaders
let uv_webgpu = page0.uv_frames[0]// Scalable SVG preview
///|
let svg = @moon_binpack.to_svg(512, 512, best_res.rects, title="Atlas Preview")
// TexturePacker / Pixi.js / Phaser JSON manifest
///|
let pixi_json = @moon_binpack.to_pixi_json(
512,
512,
best_res.rects,
image_name="atlas.png",
)
// Production CSS sprite classes
///|
let css = @moon_binpack.to_css(best_res.rects, class_prefix="sprite")
// CSV layout table for spreadsheet / CAD
///|
let csv = @moon_binpack.to_csv(best_res.rects)
// Standalone interactive dark-mode HTML inspection dashboard
///|
let html = @moon_binpack.to_html(
512,
512,
best_res.rects,
title="Quality Inspection Report",
)moon run cmd/mainmoon testTotal tests: 48, passed: 48, failed: 0.fn AtlasBaker::bake_best(self : AtlasBaker, items : Array[ImageItem]) -> (Array[BakedAtlas], String)pub(all) struct AtlasOptions {
max_width : Int
max_height : Int
padding : Int
border_padding : Int
allow_rotation : Bool
auto_grow_pot : Bool
heuristic : MaxRectsHeuristic
} derive(Eq, Debug)fn AtlasPacker::pack_guillotine(self : AtlasPacker, items : Array[Size], merge? : Bool, rect_choice? : GuillotineHeuristic, split_method? : SplitHeuristic) -> AtlasResultfn AtlasPacker::pack_shelf(self : AtlasPacker, items : Array[Size], heuristic? : ShelfHeuristic) -> AtlasResultfn AtlasPacker::pack_skyline(self : AtlasPacker, items : Array[Size], heuristic? : SkylineHeuristic) -> AtlasResultfn GuillotinePacker::insert(self : GuillotinePacker, width : Int, height : Int, id? : Int, merge? : Bool, rect_choice? : GuillotineHeuristic, split_method? : SplitHeuristic) -> Rect?fn GuillotinePacker::insert_batch(self : GuillotinePacker, sizes : Array[Size], merge? : Bool, rect_choice? : GuillotineHeuristic, split_method? : SplitHeuristic) -> (Array[Rect], Array[Size])fn MaxRectsPacker::insert(self : MaxRectsPacker, width : Int, height : Int, id? : Int, heuristic? : MaxRectsHeuristic, allow_rotation? : Bool) -> Rect?fn MaxRectsPacker::insert_batch(self : MaxRectsPacker, sizes : Array[Size], heuristic? : MaxRectsHeuristic, allow_rotation? : Bool) -> (Array[Rect], Array[Size])fn PackingStats::compute(total_items : Int, packed : Array[Rect], unpacked : Array[Size], bins_used : Int, bin_area : Int) -> PackingStatsfn PixelBuffer::blit(self : PixelBuffer, src : PixelBuffer, dst_x : Int, dst_y : Int, rotated? : Bool) -> Unitfn PixelBuffer::draw_rect(self : PixelBuffer, x : Int, y : Int, width : Int, height : Int, color : Rgba, fill? : Bool) -> Unitfn ShelfPacker::insert(self : ShelfPacker, width : Int, height : Int, id? : Int, heuristic? : ShelfHeuristic) -> Rect?fn ShelfPacker::insert_batch(self : ShelfPacker, sizes : Array[Size], heuristic? : ShelfHeuristic) -> (Array[Rect], Array[Size])pub struct SkylinePacker {
bin_width : Int
bin_height : Int
skyline : Array[SkylineNode]
used_rectangles : Array[Rect]
used_surface_area : Int
} derive(Debug)fn SkylinePacker::insert(self : SkylinePacker, width : Int, height : Int, id? : Int, heuristic? : SkylineHeuristic, allow_rotation? : Bool) -> Rect?fn SkylinePacker::insert_batch(self : SkylinePacker, sizes : Array[Size], heuristic? : SkylineHeuristic, allow_rotation? : Bool) -> (Array[Rect], Array[Size])fn best_pack(items : Array[Size], max_width? : Int, max_height? : Int, padding? : Int, border_padding? : Int, allow_rotation? : Bool, auto_grow_pot? : Bool) -> (AtlasResult, String)Install
Download zipIndustrial-grade 2D rectangle bin packing and texture atlas layout engine in pure MoonBit.