快速将图像划分为图像阵列 [英] Divide image in array of images with swift

查看:96
本文介绍了快速将图像划分为图像阵列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将图像划分为16个图像(以矩阵形式).我正在使用Swift 2.1.这是代码:

I'm trying to divide an image to create 16 out of it (in a matrix). I'm using swift 2.1. Here's the code:

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的高度.

This works but the images that returns are only part of the original image. I've been searching and I know that's because when I create a CGImage it has a size different than the UIImage, but I don't know how to fix it. If I could make the variable cellSize with the height of the CGImage instead of the UIImage I suppose I would fix it but I can't get the CGImage height.

感谢您的帮助!

推荐答案

基本问题是UIImageCGImage解释其size的方式之间的区别. UIImage使用点",而CGImage使用像素.转换因子为 scale .

The fundamental issue is the difference between how UIImage and CGImage interpret their size. UIImage uses "points" and CGImage uses pixels. And the conversion factor is the scale.

例如,如果UIImagescale为3,则在UIImage的任何给定方向上的每个点"都在基础CGImage中的该方向上有三个像素.因此,对于UIImagescale为3,size的像素为100x100点,基础CGImage的大小为300x300像素.

For example, if a UIImage has a scale of 3, every "point" in any given direction the UIImage, there are three pixels in that direction in the underlying CGImage. So for a UIImage that has a scale of 3 and a size of 100x100 points, the underlying CGImage has a size of 300x300 pixels.

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

To return a simple array of images sliced by n x n (e.g. if n is three, there will be nine images in the array), you can do something like the following in 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中:

Or, in 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点的图像制作三个图块时,前两个将为245点,而最后一个将为246点).

This makes sure that the resulting images are in the correct scale (this is why the above strides through the image in "points" and the multiplies to get the correct pixels in the CGImage). This also, if the dimensions, measured in "points") are not evenly divisible by n, it will making up the difference in the last image for that row or column, respectively. E.g. when you make three tiles for an image with a height of 736 points, the first two will be 245 points, but the last one will be 246 points).

有一个例外,那就是它不能(完全)优雅地处理.也就是说,如果UIImageimageOrientation不同于.up,则检索图像的顺序对应于该方向,而不是查看时图像的左上角.

There is one exception that this does not (entirely) handle gracefully. Namely, if the UIImage has an imageOrientation of something other than .up, the order in which the images is retrieved corresponds to that orientation, not the upper left corner of the image as you view it.

这篇关于快速将图像划分为图像阵列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆