Sprite outline and save
Question: 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!")
    


Answer: 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.

