用swift划分图像阵列中的图像

JJd*_*dip 5 uiimage ios swift swift2

我正在尝试将图像分割成16个(在矩阵中).我正在使用swift 2.1.这是代码:

let cellSize = Int(originalImage.size.height) / 4

for i in 0...4 {
        for p in 0...4 {
            let tmpImgRef: CGImage = originalImage.CGImage!

            let rect: CGImage = CGImageCreateWithImageInRect(tmpImgRef, CGRectMake(CGFloat(i * cellSize), CGFloat(p * cellSize), CGFloat(cellSize), CGFloat(cellSize)))!

            gameCells.append(cell)

        }
    }
Run Code Online (Sandbox Code Playgroud)

这有效,但返回的图像只是原始图像的一部分.我一直在搜索,我知道那是因为当我创建一个CGImage时,它的大小与UIImage不同,但我不知道如何修复它.如果我可以使用CGImage的高度而不是UIImage来制作变量cellSize,我想我会修复它,但我无法获得CGImage高度.

谢谢您的帮助!

Rob*_*Rob 6

根本问题是如何UIImageCGImage解释它们之间的区别sizeUIImage使用“点”并CGImage使用像素。并且转换因子是scale

例如,如果 a 的UIImageascale为 3,则在任何给定方向 的每个“点”,UIImage在底层 的该方向上都有三个像素CGImage。因此UIImage,对于 ascale为 3 和 asize为 100x100 点的 a,底层CGImage的大小为 300x300 像素。

要返回由n x n切片的简单图像数组(例如,如果n为 3,则数组中将有 9 个图像),您可以在 Swift 3 中执行以下操作:

/// Slice image into array of tiles
///
/// - Parameters:
///   - image: The original image.
///   - howMany: How many rows/columns to slice the image up into.
///
/// - Returns: An array of images.
///
/// - Note: The order of the images that are returned will correspond
///         to the `imageOrientation` of the image. If the image's
///         `imageOrientation` is not `.up`, take care interpreting 
///         the order in which the tiled images are returned.

func slice(image: UIImage, into howMany: Int) -> [UIImage] {
    let width: CGFloat
    let height: CGFloat

    switch image.imageOrientation {
    case .left, .leftMirrored, .right, .rightMirrored:
        width = image.size.height
        height = image.size.width
    default:
        width = image.size.width
        height = image.size.height
    }

    let tileWidth = Int(width / CGFloat(howMany))
    let tileHeight = Int(height / CGFloat(howMany))

    let scale = Int(image.scale)
    var images = [UIImage]()

    let cgImage = image.cgImage!

    var adjustedHeight = tileHeight

    var y = 0
    for row in 0 ..< howMany {
        if row == (howMany - 1) {
            adjustedHeight = Int(height) - y
        }
        var adjustedWidth = tileWidth
        var x = 0
        for column in 0 ..< howMany {
            if column == (howMany - 1) {
                adjustedWidth = Int(width) - x
            }
            let origin = CGPoint(x: x * scale, y: y * scale)
            let size = CGSize(width: adjustedWidth * scale, height: adjustedHeight * scale)
            let tileCgImage = cgImage.cropping(to: CGRect(origin: origin, size: size))!
            images.append(UIImage(cgImage: tileCgImage, scale: image.scale, orientation: image.imageOrientation))
            x += tileWidth
        }
        y += tileHeight
    }
    return images
}
Run Code Online (Sandbox Code Playgroud)

或者,在 Swift 2.3 中:

func slice(image image: UIImage, into howMany: Int) -> [UIImage] {
    let width: CGFloat
    let height: CGFloat

    switch image.imageOrientation {
    case .Left, .LeftMirrored, .Right, .RightMirrored:
        width = image.size.height
        height = image.size.width
    default:
        width = image.size.width
        height = image.size.height
    }

    let tileWidth = Int(width / CGFloat(howMany))
    let tileHeight = Int(height / CGFloat(howMany))

    let scale = Int(image.scale)
    var images = [UIImage]()
    let cgImage = image.CGImage!

    var adjustedHeight = tileHeight

    var y = 0
    for row in 0 ..< howMany {
        if row == (howMany - 1) {
            adjustedHeight = Int(height) - y
        }
        var adjustedWidth = tileWidth
        var x = 0
        for column in 0 ..< howMany {
            if column == (howMany - 1) {
                adjustedWidth = Int(width) - x
            }
            let origin = CGPoint(x: x * scale, y: y * scale)
            let size = CGSize(width: adjustedWidth * scale, height: adjustedHeight * scale)
            let tileCgImage = CGImageCreateWithImageInRect(cgImage, CGRect(origin: origin, size: size))!
            images.append(UIImage(CGImage: tileCgImage, scale: image.scale, orientation: image.imageOrientation))
            x += tileWidth
        }
        y += tileHeight
    }
    return images
}
Run Code Online (Sandbox Code Playgroud)

这可确保生成的图像正确无误scale(这就是为什么上述步骤以“点”的形式遍历图像并相乘以获得 中的正确像素的原因CGImage)。这也是,如果以“点”为单位测量的尺寸不能被n整除,它将分别弥补该行或列的最后一个图像中的差异。例如,当您为高度为 736 点的图像制作三个拼贴时,前两个将是 245 点,但最后一个将是 246 点)。

有一个例外,这不会(完全)优雅地处理。即,如果UIImage具有 以外的imageOrientation其他内容.up,则检索图像的顺序对应于该方向,而不是您查看时图像的左上角。