Skip to content

Instantly share code, notes, and snippets.

@danman113
Created January 2, 2020 23:39
Show Gist options
  • Save danman113/61b41a27913829d81862cdaa85657ea5 to your computer and use it in GitHub Desktop.
Save danman113/61b41a27913829d81862cdaa85657ea5 to your computer and use it in GitHub Desktop.
~50 Line Texture Packer
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