ios - 用swift将图像划分为图像数组

标签 ios swift swift2 uiimage

我正在尝试划分图像以从中创建 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)

        }
    }

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

感谢您的帮助!

最佳答案

根本问题是 UIImageCGImage 如何解释它们的大小 之间的差异。 UIImage 使用“点”,CGImage 使用像素。转换因子是 scale .

例如,如果 UIImagescale 为 3,则 UIImage 任何给定方向上的每个“点”,都有三个底层 CGImage 中那个方向的像素。因此,对于 scale 为 3 且 size 为 100x100 点的 UIImage,底层 CGImage 有一个大小为 300x300 像素。

返回一个由 n x n 切片的简单图像数组(例如,如果 n 为三,则将有九张图像数组),您可以在 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
}

或者,在 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
}

这确保生成的图像在正确的 scale 中(这就是为什么上面以“点”跨越图像并乘以在 CGImage 中获得正确像素的原因)。同样,如果以“点”为单位测量的尺寸不能被 n 整除,它将分别弥补最后一张图像中该行或该列的差异。例如。当你为一个高度为 736 点的图像制作三个图 block 时,前两个将是 245 点,但最后一个将是 246 点)。

有一个异常(exception),这并没有(完全)优雅地处理。即,如果 UIImageimageOrientation 不是 .up,则检索图像的顺序对应于该方向,而不是在您查看图像时显示在图像的左上角。

关于ios - 用swift将图像划分为图像数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43008098/

相关文章:

ios - CocoaPods - 无法找到规范

ios - 约束在 iPhone X 与 8 上表现异常(Xcode Bug?)

swift - iad 的 didFailToReceiveAdWithError 函数不工作

ios - 在 Swift 中将 UIImage 转换为 UInt8 数组

swift - 设置委托(delegate)会导致崩溃,将其保留为空则不会

ios - Swift 导航栏正在更改状态栏文本颜色

ios - 如何获取模态呈现 View Controller 的 Root View 高度?

xcode - Swift ScrollView 分页只显示数组中的最后一张图像

ios - 为条形按钮项目设置图像和标题?

ios - UITableView 中的 insertRowsAtIndexPaths 添加重复行