Search code examples
swiftimagesprite-kitcroptile

Split Picture in tiles and put in array


I have a large Tilesheet (over 1000 tiles in one picture) like this: enter image description here

Each tile is 64x64 and I want to split the picture. in this example I would be 4 tiles and put in an array. How can I do this? with different sizes? I need some magic (math) or better an idea how can I get the right position to crop in the loop.

Some fast coded Code:

func cropImage(image: UIImage, tileSize: Int) -> [UIImage]? {
    if Int(image.size.height) % 64 != 0 && Int(image.size.width) % 64 != 0 {
        return nil
    }

    let hCount = Int(image.size.height) / tileSize
    let wCount = Int(image.size.width) / tileSize

    var tiles:[UIImage] = []

    for i in 0...hCount {
        for p in 0...wCount {
            let temp:CGImage = image.cgImage!.cropping(to: CGRect.zero)!
            tiles.append(UIImage(cgImage: temp))
        }
    }
    return tiles
}

Solution

  • On every pass through the loop, you need two pieces of information:

    1. What is the size of the tile? This will be same for all tiles; you only need to calculate it once, before the loop.

    2. What is the origin of the tile? This will be different for each tile. You will cycle both through the x-count and the y-count, and in the innermost loop you'll calculate the origin for this tile (i.e. with this x and y), based on the tile size which you already know.

    Now you know the exact rect of the original image that is to be used for this tile. The rest is straightforward.

    However, I would suggest giving some thought to the actual way in which you crop to that rect. You are proposing to crop by calling CGImage's cropping(to:). However, in a similar situation, that is not what I do. I make a UIImage by drawing the original UIImage at the negative of the desired origin into an image graphics context of the desired size.