Roi Mulia
Roi Mulia

Reputation: 5896

Create CIImage Pattern from image file

I'm trying to understand what is the most efficient way to create a CIImage with a pattern, based on an image file.

let patternImage = UIImage(named: "pattern.png")

The first approach I took:

// First create UIColor pattern
let uiColorPattern = UIColor(patternImage: patternImage!) 

// Than init CIColor using the UIColor pattern object
let ciColorPattern = CIColor(color: uiColorPattern)

// Finally, create CIImage using the CIColor initialiser
let ciImagePattern = CIImage(color: ciColorPattern) //

Sadly, for unknown reason the CIImage is simply blank. I also tried applying clampedToExtent() and than cropping it but it still blank.

The second approach I took (works but too slow):

UIGraphicsBeginImageContext(size) // create context

patternImage?.drawAsPattern(in: rect) // draw pattern as 'UIImage'

let patternUIImage = UIGraphicsGetImageFromCurrentImageContext() // fetch 'UIImage'

UIGraphicsEndImageContext() // end context

if let patternUIImage = patternUIImage {
     let ciImagePattern = CIImage(image: patternUIImage) // Create 'CIImage' using 'UIImage'
}    

this method works but as I said, too slow.


In general, my intuition was that if I could make the first approach work, it'll be a lot more efficient than the second approach.

Any other approaches/suggestions would be highly appreciated!

Upvotes: 4

Views: 536

Answers (1)

Md. Ibrahim Hassan
Md. Ibrahim Hassan

Reputation: 5477

The first approach you are taking would not work as From WWDC 2013:

So, because, you know, and CIColor doesn't handle color spaces, it won't do CMYK color, it won't do patterns.

So, these are all things that you're going to lose.

If you ever think that you're going to need that, then probably not the right strategy.

So the second approach is what we can optimise on. I have a snippet which returns a pattern image you can give it a try.

        let myImage = UIImage.init(named: "www")
        let imageSize = myImage?.size
        let imageWidth = imageSize?.width
        let imageHeight = imageSize?.height
        let widthIterations = self.view.bounds.size.width / imageWidth!
        let heightIterations = self.view.bounds.size.height / imageHeight!

        UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, true, UIScreen.main.scale)
        let context = UIGraphicsGetCurrentContext()


            for i in 0 ... Int(heightIterations) {
                let yPoint = CGFloat(i) * imageHeight!
                for j in 0 ... Int(widthIterations) {
                    let xPoint = CGFloat(j) * imageWidth!
                    myImage?.draw(at: CGPoint.init(x: xPoint, y: yPoint))
                }
            }
        let tempImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

enter image description here

Further reading

Upvotes: 3

Related Questions