将图片拆分为图块并放入数组

Split Picture in tiles and put in array

我有一个很大的 Tilesheet(一张图片中有超过 1000 个图块),如下所示:

每个图块都是 64x64,我想拆分图片。在这个例子中,我将 4 个瓷砖放在一个数组中。我怎样才能做到这一点?有不同的尺寸?我需要一些魔法(数学)或更好的想法,我怎样才能在循环中获得正确的裁剪位置。

一些快速编码代码:

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
}

在每次通过循环时,您需要两条信息:

  1. 瓷砖的尺寸是多少?这对所有瓷砖都是一样的;你只需要在循环之前计算一次。

  2. 瓷砖的来源是什么?这对于每个图块都是不同的。您将在 x-count 和 y-count 之间循环,在最内层的循环中,您将计算 this 方块的原点(即使用 x 和 y ),基于您已知的图块大小。

现在您知道要用于 this 拼贴的原始图像的确切矩形。剩下的就简单了。

但是,我建议考虑一下裁剪到该矩形的实际方式。您提议通过调用 CGImage 的 cropping(to:) 进行裁剪。但是,在类似的情况下,这不是我所做的。我通过将原始 UIImage 在所需原点的负值绘制到所需大小的图像图形上下文中来制作 UIImage。

我根据 Matt 的回答为下一位读者制作代码:

func cropImage(image: UIImage, tileSize: Int) -> [UIImage]? {
        let hCount = Int(image.size.height) / tileSize
        let wCount = Int(image.size.width) / tileSize

        var tiles:[UIImage] = []

        for i in 0...hCount-1 {
            for p in 0...wCount-1 {
                let rect = CGRect(x: p*tileSize, y: i*tileSize, width: tileSize, height: tileSize)
                let temp:CGImage = image.cgImage!.cropping(to: rect)!
                tiles.append(UIImage(cgImage: temp))
            }
        }
        return tiles
    }

参数图像:tilesheet(原始图像)

参数 tileSize:图块大小(长度或宽度)

func splitImage(row : Int , column : Int){

    let oImg = userImage.image

    let height =  (userImage.image?.size.height)! /  CGFloat (row) //height of each image tile
    let width =  (userImage.image?.size.width)!  / CGFloat (column)  //width of each image tile

    let scale = (userImage.image?.scale)! //scale conversion factor is needed as UIImage make use of "points" whereas CGImage use pixels.

    imageArr = [[UIImage]]() // will contain small pieces of image
    for y in 0..<row{
        var yArr = [UIImage]()
        for x in 0..<column{

            UIGraphicsBeginImageContextWithOptions(
                CGSize(width:width, height:height),
                false, 0)
            let i =  oImg?.cgImage?.cropping(to:  CGRect.init(x: CGFloat(x) * width * scale, y:  CGFloat(y) * height * scale  , width: (width * scale) , height: (height * scale)) )

            let newImg = UIImage.init(cgImage: i!)

            yArr.append(newImg)

            UIGraphicsEndImageContext();
        }
        imageArr.append(yArr)
    }
}