Advertisement
Guest User

/r/pokemon sprite cropper

a guest
Apr 3rd, 2012
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.84 KB | None | 0 0
  1. from PIL import Image
  2.  
  3. BLANK = (255, 255, 255)
  4.  
  5. class Sprite:
  6.     """Represents a single icon on the sprite sheet. Has a width, height,
  7.    left offset, right offset, and top offset."""
  8.    
  9.     def __init__(self, top):
  10.         self.top = top
  11.         self.width = 0
  12.         self.height = 0
  13.        
  14.         # We update the offsets when the row's offset is smaller, so start
  15.         # them impossibly high
  16.         self.left = float('inf')
  17.         self.right = float('inf')
  18.    
  19.     def add_row(self, row):
  20.         """Add an ImageRow to this sprite, updating offsets and dimensions."""
  21.         # The left offset of a sprite is the minimal left offset of all its
  22.         # rows. Same goes for right. So, take the min of our current offset
  23.         # and the row's offset so that, by the end, we'll have each offset
  24.         # as the min of the corresponding offsets in each row.
  25.         self.left = min(self.left, row.significant_left)
  26.         self.right = min(self.right, row.significant_right)
  27.        
  28.         # Update our dimensions while we're here, too.
  29.         self.width = (row.width - self.right) - self.left
  30.         self.height += 1
  31.  
  32. class ImageRow:
  33.     """Represents a single row of pixels in the image. Has a width,
  34.    top offset, significant left offset (where the non-blank pixels start, if
  35.    there are any), and significant right offset."""
  36.    
  37.     def __init__(self, pix, width, y):
  38.         self._pix = pix
  39.         self.width = width
  40.         self.y = y
  41.        
  42.         left_to_right = xrange(self.width)      # 0 ... (width - 1)
  43.         right_to_left = reversed(left_to_right) # (width - 1) ... 0
  44.        
  45.         # Find left offset and right offset of this row's significant section
  46.         self.significant_left = self._significant_offset(left_to_right)
  47.         self.significant_right = self._significant_offset(right_to_left)
  48.    
  49.     def is_significant(self):
  50.         """Is this row significant (non-blank)? True or False."""
  51.         return self.significant_left != None
  52.    
  53.     def _significant_offset(self, seq):
  54.         """Given a sequence of x-offsets, return the first (if any) whose
  55.        corresponding pixel is significant (non-blank)."""
  56.         for offset, x in enumerate(seq):
  57.             if self._pix[x, self.y] != BLANK:
  58.                 return offset
  59.         return None
  60.  
  61. # Open up the image, convert to RGB if it's not RGB yet, find dimensions
  62. sheet = Image.open("pkmn_icons.png").convert("RGB")
  63. width, height = sheet.size
  64.  
  65. # Load the pixel accessor object (reads from here are faster than
  66. # sheet.getpixel)
  67. pix = sheet.load()
  68.  
  69. # Set up our list of sprites to populate
  70. sprites = []
  71.  
  72. # Loop through the rows of the image, keeping track of if we're working on
  73. # a sprite right now or not
  74. current_sprite = None
  75. for y in xrange(height):
  76.     row = ImageRow(pix, width, y)
  77.    
  78.     if row.is_significant(): # row is non-blank
  79.  
  80.         # If there is no current sprite, this is the first row of a new
  81.         # sprite. Set that sucker up.
  82.         if not current_sprite:
  83.             current_sprite = Sprite(y)
  84.             sprites.append(current_sprite)
  85.        
  86.         # Add this row to the current sprite, which will update its width,
  87.         # height, and offsets accordingly.
  88.         current_sprite.add_row(row)
  89.        
  90.     elif current_sprite: # row is blank and there is a current sprite
  91.        
  92.         # This is the first blank row after a sprite. The sprite is complete.
  93.         current_sprite = None
  94.  
  95. # Print the CSS line for each sprite
  96. for i, sprite in enumerate(sprites):
  97.     selector = ".flair-{0}::before".format(i + 1)
  98.    
  99.     rules = []
  100.     rules.append("width:{0}px".format(sprite.width))
  101.     rules.append("height:{0}px".format(sprite.height))
  102.     rules.append("background-position:{0}px {1}px".format(-sprite.left, -sprite.top))
  103.    
  104.     print selector + "{" + ";".join(rules) + "}"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement