Split image in an array of images with fast

I am trying to split an image to create 16 of it (in a matrix). I am using fast 2.1. Here is 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)

        }
    }

This works, but the returned images are only part of the original image. I searched, and I know this, because when I create a CGImage, it has a size different from UIImage, but I don’t know how to fix it. If I could make a cellSize variable with a height of CGImage instead of UIImage, I suppose I will fix it, but I cannot get the height of CGImage.

Thanks for the help!

+4
source share
3 answers

, UIImage CGImage size. UIImage "", CGImage - . - scale.

, a UIImage scale 3, "" UIImage, CGImage . , UIImage, scale of 3 a size 100x100 , CGImage 300 × 300 .

, 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 , 245 , 246 ).

, - () . , UIImage imageOrientation - , .up, , , , .

+2

im , :

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..<rows).forEach { row in
            (0..<columns).forEach { column in
                var width = Int(x)
                var height = Int(y)
                if row == rows-1 && size.height.truncatingRemainder(dividingBy: CGFloat(rows)) != 0 {
                    height = Int(size.height - size.height / CGFloat(rows) * (CGFloat(rows)-1))
                }
                if column == columns-1 && size.width.truncatingRemainder(dividingBy: CGFloat(columns)) != 0 {
                    width = Int(size.width - (size.width / CGFloat(columns) * (CGFloat(columns)-1)))
                }
                if let image = cgImage.cropping(to: CGRect(origin: CGPoint(x: column * Int(x), y:  row * Int(x)), size: CGSize(width: width, height: height))) {
                    images.append(UIImage(cgImage: image, scale: scale, orientation: imageOrientation))
                }
            }
        }
        return images
    }
}

let myPicture = UIImage(data: try! Data(contentsOf: URL(string:"https://i.stack.imgur.com/Xs4RX.jpg")!))!

let images = myPicture.matrix(4, 4)

images.count   // 16
+3

I used this to slice an image into a matrix. The matrix is ​​represented as a 1D array.

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
    }
0
source

Source: https://habr.com/ru/post/1673161/


All Articles