Created
January 2, 2020 23:39
-
-
Save danman113/61b41a27913829d81862cdaa85657ea5 to your computer and use it in GitHub Desktop.
~50 Line Texture Packer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const path = require('path') | |
const fs = require('fs') | |
const sharp = require('sharp') | |
const ShelfPack = require('@mapbox/shelf-pack') | |
const debug = process.env.DEBUG || false | |
const padding = +process.env.PADDING || 0 | |
const output = process.env.OUTPUT || 'out' | |
const dir = process.env.DIR || 'images' | |
const images = fs.readdirSync(dir).map(img => path.join(dir, img)) | |
if (debug) console.log(padding, output, dir, images) | |
const main = async () => { | |
const imageMetadata = (await Promise.all( | |
images.map(img => sharp(img).metadata()) | |
)).map(obj => | |
// Adds a padding offset to each image. Because sharp simply composes using the default width/height, this adds a {padding} offset to the bottom and right of each image | |
Object.assign(obj, { | |
width: obj.width + padding, | |
height: obj.height + padding, | |
}) | |
) | |
let box = [] | |
let size = 16 // We're going to assume these images are at least > 32px | |
// if the output from shelfpack contains all images, we're done. Also stop if size overflows, we don't need images that big | |
while (box.length !== imageMetadata.length && size > 0) { | |
size = size << 1 | |
const pack = new ShelfPack(size, size) | |
box = pack.pack(imageMetadata) | |
} | |
if (debug) console.log(box) | |
// This just turns the output from shelfPack into a format that sharp can understand | |
const boxWithImages = box.map(fittedCoords => ({ | |
input: images[fittedCoords.id - 1], | |
left: fittedCoords.x, | |
top: fittedCoords.y, | |
width: fittedCoords.width, | |
height: fittedCoords.height | |
})) | |
await sharp() | |
.resize(size, size) | |
.composite(boxWithImages) | |
.png() | |
.toFile(`${output}.png`) | |
fs.writeFileSync(`${output}.json`, JSON.stringify(boxWithImages), { | |
encoding: 'utf8', | |
}) | |
} | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment