import sharp from 'sharp'; import { resolve, basename, extname, join, dirname } from 'path'; import { existsSync, mkdirSync, readdirSync, statSync } from 'fs'; import { fileURLToPath } from 'url'; const PROJECT_ROOT = resolve(fileURLToPath(import.meta.url), '../../..'); const DEFAULT_INPUT = resolve(PROJECT_ROOT, 'assets/items'); const DEFAULT_OUTPUT = resolve(PROJECT_ROOT, 'assets/icons'); const GRID = 4; const SUPPORTED_EXTENSIONS = /\.(jpe?g|png|webp|tiff?)$/i; async function splitSpriteSheet(filePath, outputDir) { const name = basename(filePath, extname(filePath)); const { width, height } = await sharp(filePath).metadata(); const cellWidth = Math.floor(width / GRID); const cellHeight = Math.floor(height / GRID); const tasks = []; for (let row = 0; row < GRID; row++) { for (let col = 0; col < GRID; col++) { const left = col * cellWidth; const top = row * cellHeight; const outputPath = join(outputDir, `${name}-${row}-${col}.png`); tasks.push( sharp(filePath) .extract({ left, top, width: cellWidth, height: cellHeight }) .png() .toFile(outputPath) .then(() => outputPath) ); } } return Promise.all(tasks); } function collectFiles(input) { if (statSync(input).isFile()) { return [input]; } return readdirSync(input) .filter(f => SUPPORTED_EXTENSIONS.test(f)) .map(f => join(input, f)); } async function main() { const input = resolve(process.argv[2] || DEFAULT_INPUT); const outputDir = resolve(process.argv[3] || DEFAULT_OUTPUT); if (!existsSync(input)) { console.error(`Not found: ${input}`); process.exit(1); } mkdirSync(outputDir, { recursive: true }); const files = collectFiles(input); if (files.length === 0) { console.error(`No image files found in: ${input}`); process.exit(1); } console.log(`Processing ${files.length} sprite sheet(s)...`); const allResults = await Promise.all( files.map(async (filePath) => { const results = await splitSpriteSheet(filePath, outputDir); console.log(` ${basename(filePath)} -> ${results.length} images`); return results; }) ); const totalImages = allResults.reduce((sum, r) => sum + r.length, 0); console.log(`Done. ${totalImages} images saved to ${outputDir}`); } main();