用swift划分图像arrays中的图像

我正在尝试将图像分割成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如何解释它们的sizeUIImage使用“points”, CGImage使用像素。 转换因子是scale

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

要返回由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 } 

或者,在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点)。

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

您可以将图像垂直和水平分割成两部分,然后根据需要进行子分割:

 extension UIImage { var topHalf: UIImage? { guard let cgImage = cgImage, let image = cgImage.cropping(to: CGRect(origin: .zero, size: CGSize(width: size.width, height: size.height/2))) else { return nil } return UIImage(cgImage: image, scale: scale, orientation: imageOrientation) } var bottomHalf: UIImage? { guard let cgImage = cgImage, let image = cgImage.cropping(to: CGRect(origin: CGPoint(x: 0, y: CGFloat(Int(size.height)-Int(size.height/2))), size: CGSize(width: size.width, height: CGFloat(Int(size.height) - Int(size.height/2))))) else { return nil } return UIImage(cgImage: image, scale: scale, orientation: imageOrientation) } var leftHalf: UIImage? { guard let cgImage = cgImage, let image = cgImage.cropping(to: CGRect(origin: .zero, size: CGSize(width: size.width/2, height: size.height))) else { return nil } return UIImage(cgImage: image, scale: scale, orientation: imageOrientation) } var rightHalf: UIImage? { guard let cgImage = cgImage, let image = cgImage.cropping(to: CGRect(origin: CGPoint(x: CGFloat(Int(size.width)-Int((size.width/2))), y: 0), size: CGSize(width: CGFloat(Int(size.width)-Int((size.width/2))), height: size.height))) else { return nil } return UIImage(cgImage: image, scale: scale, orientation: imageOrientation) } var splitedInFourParts: [UIImage] { guard case let topHalf = topHalf, case let bottomHalf = bottomHalf, let topLeft = topHalf?.leftHalf, let topRight = topHalf?.rightHalf, let bottomLeft = bottomHalf?.leftHalf, let bottomRight = bottomHalf?.rightHalf else{ return [] } return [topLeft, topRight, bottomLeft, bottomRight] } var splitedInSixteenParts: [UIImage] { var array = splitedInFourParts.flatMap({$0.splitedInFourParts}) // if you need it in reading order you need to swap some image positions swap(&array[2], &array[4]) swap(&array[3], &array[5]) swap(&array[10], &array[12]) swap(&array[11], &array[13]) return array } } 

按列和行拆分图像:

 extension UIImage { func matrix(_ rows: Int, _ columns: Int) -> [UIImage] { let y = (size.height / CGFloat(rows)).rounded() let x = (size.width / CGFloat(columns)).rounded() var images: [UIImage] = [] images.reserveCapacity(rows * columns) guard let cgImage = cgImage else { return [] } (0.. 

 let myPicture = UIImage(data: try! Data(contentsOf: URL(string:"http://sofzh.miximages.com/ios/Xs4RX.jpg")!))! let images = myPicture.matrix(4, 4) images.count // 16 

我用它来将图像切割成矩阵。 矩阵表示为1Darrays。

 func snapshotImage(image: UIImage, rect: CGRect) -> UIImage { var imageRect: CGRect! = rect if image.scale > 1.0 { imageRect = CGRect(origin: CGPoint(x: rect.origin.x * image.scale, y: rect.origin.y * image.scale), size: CGSize(width: rect.size.width * image.scale, height: rect.size.height * image.scale)) } let imageRef: CGImage = image.cgImage!.cropping(to: imageRect)! let result: UIImage = UIImage(cgImage: imageRef, scale: image.scale, orientation: image.imageOrientation) return result } func sliceImage(image: UIImage, size: CGSize) -> [UIImage] { var slices: [UIImage] = [UIImage]() var rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height) var y: Float = 0.0 let width: Int = Int(image.size.width / size.width) let height: Int = Int(image.size.height / size.height) for _ in 0...height { var x: Float = 0.0 for _ in 0...width { rect.origin.x = CGFloat(x); slices.append(self.snapshotImage(image: image, rect: rect)) x += Float(size.width) } y += Float(size.height) rect.origin.y = CGFloat(y) } return slices }