Search code examples
image-processingswiftios8cropcore-image

iOS 8 Core Image saving a section of an Image via Swift


I'm using CoreImage Framework for detecting Business Card. When I detect a rectangle (CIDetectorTypeRectangle) I draw an overlay using this method:

    func drawOverlay(image: CIImage, topLeft: CGPoint, topRight: CGPoint, bottomLeft: CGPoint, bottomRight: CGPoint) -> CIImage {

    var overlay = CIImage(color: CIColor(red: 0, green: 0, blue: 1.0, alpha: 0.3))
    overlay = overlay.imageByCroppingToRect(image.extent())
    overlay = overlay.imageByApplyingFilter("CIPerspectiveTransformWithExtent",
      withInputParameters: [
        "inputExtent": CIVector(CGRect: image.extent()),
        "inputTopLeft": CIVector(CGPoint: topLeft),
        "inputTopRight": CIVector(CGPoint: topRight),
        "inputBottomLeft": CIVector(CGPoint: bottomLeft),
        "inputBottomRight": CIVector(CGPoint: bottomRight)
      ])
    return overlay.imageByCompositingOverImage(image)
  }

Now I need to take automatically a picture of the selected area and save it. Does anyone know how to do it? Thanks!


Solution

  • I have found the solution!

    func cropBusinessCardForPoints(image: CIImage, topLeft: CGPoint, topRight: CGPoint, bottomLeft: CGPoint, bottomRight: CGPoint) -> CIImage {
    
            var businessCard: CIImage
            businessCard = image.imageByApplyingFilter("CIPerspectiveTransformWithExtent",
                withInputParameters: [
                    "inputExtent": CIVector(CGRect: image.extent()),
                    "inputTopLeft": CIVector(CGPoint: topLeft),
                    "inputTopRight": CIVector(CGPoint: topRight),
                    "inputBottomLeft": CIVector(CGPoint: bottomLeft),
                    "inputBottomRight": CIVector(CGPoint: bottomRight)
                ])
            businessCard = image.imageByCroppingToRect(businessCard.extent())
    
            return businessCard
        }
    

    Usage:

    //Variables
        var context: CIContext!
        var orientation: UIImageOrientation = UIImageOrientation.Right
    
    
    
    override func viewDidLoad() {
            super.viewDidLoad()
    
            //Initialize the CIContext
            context = CIContext(options:nil)
    
            ...
    }
    

    When a rectangle is detected:

    //...
    
    let businessCardImage = cropBusinessCardForPoints(image, topLeft: feature.topLeft, topRight: feature.topRight, bottomLeft: feature.bottomLeft, bottomRight: feature.bottomRight)
    
    //Convert CIImage to CGImage
    let cgimg = context.createCGImage(businessCardImage, fromRect: businessCardImage.extent())
    
    //Convert CGImage to UIImage
    let newImage = UIImage(CGImage: cgimg, scale:1, orientation: orientation)