Created
March 27, 2011 11:17
-
-
Save julsam/889130 to your computer and use it in GitHub Desktop.
These two classes can pack surfaces of different sizes into one big surface.
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
import pygame | |
class PackNode(object): | |
""" | |
Creates an area which can recursively pack images into itself. | |
""" | |
def __init__(self, area): | |
# if tuple contains two elements, assume they are width and height, | |
# and origin is (0,0) | |
if len(area) == 2: | |
area = (0,0,area[0],area[1]) | |
self.area = area | |
def get_width(self): | |
return self.area[2] - self.area[0] | |
width = property(fget=get_width) | |
def get_height(self): | |
return self.area[3] - self.area[1] | |
height = property(fget=get_height) | |
def insert(self, area): | |
if hasattr(self, 'child'): | |
a = self.child[0].insert(area) | |
if a is None: return self.child[1].insert(area) | |
return a | |
area = PackNode(area) | |
if area.width <= self.width and area.height <= self.height: | |
self.child = [None,None] | |
self.child[0] = PackNode((self.area[0]+area.width, self.area[1], | |
self.area[2], self.area[1] + area.height)) | |
self.child[1] = PackNode((self.area[0], self.area[1]+area.height, | |
self.area[2], self.area[3])) | |
return PackNode((self.area[0], self.area[1], | |
self.area[0]+area.width, self.area[1]+area.height)) | |
class Pack(object): | |
def __init__(self, size=(512,512)): | |
self.tree = PackNode(size) | |
self.image = pygame.Surface(size, pygame.SRCALPHA, 32) | |
self.wr = 1.0 / float(size[0]) | |
self.hr = 1.0 / float(size[1]) | |
def pack(self, img): | |
wr = self.wr | |
hr = self.hr | |
if not isinstance(img, pygame.Surface): | |
img = pygame.image.load(img).convert(32, pygame.SRCALPHA) | |
img = img.convert_alpha(img) | |
uv = self.tree.insert(img.get_size()) | |
if uv is None: raise ValueError('Pack size too small.') | |
area = tuple(uv.area) | |
self.image.blit(img, area) | |
uv = area[0] * wr, area[1] * hr, area[2] * wr, area[3] * hr | |
return (uv[0],uv[1]),(uv[0], uv[3]), (uv[2],uv[3]), (uv[2], uv[1]) | |
if __name__ == "__main__": | |
import time | |
import glob | |
pygame.init() | |
s = pygame.display.set_mode((512,512)) | |
p = Pack() | |
for filename in glob.glob("*.png"): | |
p.pack(filename) | |
pygame.image.save(p.image, 'out.png') | |
s.blit(p.image, (0,0)) | |
pygame.display.flip() | |
time.sleep(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment