secret
Created

Ponymote spritesheet packer

  • Download Gist
pmpacker.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
#!/usr/bin/env python
# -*- coding: utf8 -*-
################################################################################
##
## Copyright (C) 2012 Typhos
##
## This Source Code Form is subject to the terms of the Mozilla Public
## License, v. 2.0. If a copy of the MPL was not distributed with this
## file, You can obtain one at http://mozilla.org/MPL/2.0/.
##
################################################################################
 
import argparse
import os
import sys
 
import PIL.Image
 
def main():
parser = argparse.ArgumentParser(description="Spritesheet packer")
parser.add_argument("directory", help="Image directory")
parser.add_argument("image", help="Output image file")
parser.add_argument("css", help="Output CSS")
parser.add_argument("width", help="Width out spritesheet", type=int)
args = parser.parse_args()
 
filenames = os.listdir(args.directory)
emotes = {}
images = {}
for name in filenames:
images[os.path.splitext(name)[0]] = PIL.Image.open(os.path.join(args.directory, name))
assert all(image.size[0] <= args.width for image in images.values())
 
spritesheet = PIL.Image.new("RGBA", (args.width, 1), (0, 0, 0, 0))
 
placements = []
left = 0
top = 0
 
for (name, image) in sorted(images.items(), key=lambda ni: (ni[1].size[1], ni[1].size[0]), reverse=True):
right = left + image.size[0]
bottom = top + image.size[1]
if right >= spritesheet.size[0]:
# Move to new line...
left, right = 0, image.size[0]
top = max(placements) if placements else 0
bottom = top + image.size[1]
if bottom >= spritesheet.size[1]:
new_spritesheet = PIL.Image.new("RGBA", (spritesheet.size[0], bottom), (0, 0, 0, 0))
new_spritesheet.paste(spritesheet, (0, 0))
spritesheet = new_spritesheet
spritesheet.paste(image, (left, top))
emotes[name] = (image.size[0], image.size[1], left, top)
left = right
placements.append(bottom)
 
spritesheet.save(args.image)
 
css = open(args.css, "w")
selectors = {}
for name in emotes:
selectors[name] = "a[href|='/%s']" % (name)
css.write("""\
%s {
display: block;
float: left;
background-image: url(%%%%image%%%%)
}
""" % (", ".join(sorted(selectors.values()))))
for (name, pos) in sorted(emotes.items()):
css.write("""\
%s {
width: %spx;
height: %spx;
background-position: -%spx -%spx
}
""" % (selectors[name], pos[0], pos[1], pos[2], pos[3]))
 
if __name__ == "__main__":
main()

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.