I am making a python script that can cut out sprites from a transparent background spritesheet. I want to cut out the sprites in a square or a rectangle. So far my idea is to:
1. Get all pixel data from sheet.
2. Search for non-transparent pixels.
3. When such a pixel is found, start looking around it for other non-transparent pixels, so you can get the image correctly.
4. Append found pixels in a tuple, that then gets pushed into an image and saved.
( THE SPRITES MAY BE PLACED UNEVENLY ON THE SHEET )
If the sprite is uneven, I will check its dimensions and then add a bit of transparent background to the sides of it, so it becomes a square or a rectangle. For example you have an image that is 53x47 I will add 19 and 25 pixels of transparent background to both sides of it so it becomes a rectangle.
I am using PIL, if there is a better way to do it, feel free to share it. If you have a better way of doing it, share as well.
This is my code so far, I can't understand how to add the transparent background on the sides and how to do the outlining correctly, also I can't seem to get the neighbourPixels function right and it makes a closed loop.
from PIL import Image
from sys import argv, exit
# Functions
def neighbourPixels(pixels, row, column):
pixel = pixels[row, column]
data = tuple()
holder = tuple()
while pixel != 0:
if pixels[row+1, column][3] != 0:
holder = pixels[row+1, column]
data += (holder, )
pixel = pixels[row+1, column]
print "In box 1"
break
elif pixels[row, column+1][3] != 0:
holder = pixels[row, column+1]
data += (holder, )
pixel = pixels[row+1, column]
print "In box 2"
elif pixels[row+1, column+1][3] != 0:
holder = pixels[row+1, column+1]
data += (holder, )
pixel = pixels[row+1, column]
print "In box 3"
elif pixels[row-1, column][3] != 0:
holder = pixels[row-1, column]
data += (holder, )
pixel = pixels[row+1, column]
print "In box 4"
elif pixels[row, column-1][3] != 0:
holder = pixels[row, column-1]
data += (holder, )
pixel = pixels[row+1, column]
print "In box 5"
elif pixels[row-1, column-1][3] != 0:
holder = pixels[row-1, column-1]
data += (holder, )
pixel = pixels[row+1, column]
print "In box 6"
elif pixels[row+1, column-1][3] != 0:
holder = pixels[row+1, column-1]
data += (holder, )
pixel = pixels[row+1, column]
print "In box 7"
elif pixels[row-1, column+1][3] != 0:
holder = pixels[row-1, column+1]
data += (holder, )
pixel = pixels[row+1, column]
print "In box 8"
else:
print "Sprite has been outlined."
pixel[3] = 0
sprite = Image.new("RGBA", (len(data), len(data)))
sprite.putdata(data)
return sprite
# Main
if len(argv) < 4:
raise ValueError("Not enough arguments")
# Inicialization & Declatation
framesToCut = int(float(argv[2]))
frameSize = int(float(argv[3]))
frameToSave = Image.new("RGBA", (frameSize, frameSize))
frameCounter = 0
pixelTuple = tuple()
currentTuple = tuple()
# Preparing data
sheet = Image.open(argv[1])
width, heigth = sheet.size
pixels = sheet.load()
# Manipulation
for row in xrange(width):
for column in xrange(heigth):
# Searching for a pixel whos transparency is != 0
currentPixel = pixels[row, column]
if currentPixel[3] != 0:
print "Pixel found!"
print "Finding the sprite!"
sprite = findPixels(pixels, row, column)
if frameCounter <= framesToCut:
# left, upper, right, lower
frameCounter += 1
sprite.save(str(frameCounter), "PNG")
print "Sprite saved!"
else:
exit("Sprites were made O.o - Check 'em!")
You may want to use scikit-image's marching squares [1]. The algorithm you are looking for is already implemented.
[1] http://scikit-image.org/docs/dev/auto_examples/plot_contours.html
edit: Once you have the contours using a grey-scaled image *r_grey*, just plot colored image and contours on top of each other. This example refers to the example given at the link above:
# Find contours at a constant value of 0.8
contours = measure.find_contours(r_grey, 0.8)
# Display the image and plot all contours found
plt.imshow(r, interpolation='nearest')
for n, contour in enumerate(contours):
plt.plot(contour[:, 1], contour[:, 0], linewidth=2)
The original code told you to use r (the image) and plot it. This is what we continue to do. Remember: grey-scaled and colored image have the same coordinates.