Joe Spadafora
Joe Spadafora

Reputation: 69

Image Cropping grabbing the wrong portion of UIImage during crop

I've been working on making a view controller that will crop an image down to a specific size with some draggable control points and the background image outside of the crop zone dimmed.

For some reason whenever the image is cropped, it is grabbing the wrong reference. I've looked at just about every other post on this to deal with cropping.

Here is my setup for the Storyboard: enter image description here

I've asked a few other people including a tutor and mentor from a course that I'm taking, but we all seem to be stumped.

I can select a frame by dragging the UL UR DL DR corners around the view controller like this:

Notice the files selected from the right of the screen.

But when I press the button and use the crop function I've written, I get something that is not the correct crop based on the framed selection.

enter image description here

I also get this error message during the cropping proceedure:

 2016-09-07 23:36:38.962 ImageCropView[33133:1056024] 
  <UIView: 0x7f9cfa42c730; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x7f9cfa408400>>'s window
  is not equal to <ImageCropView.CroppedImageViewController: 0x7f9cfa43f9b0>'s view's window!

The offending part of the code must be somewhere in one of the functions below.

Here is the cropping function:

 func cropImage(image: UIImage, toRect rect: CGRect) -> UIImage {


        func rad(deg: CGFloat) -> CGFloat {
            return deg / 180.0 * CGFloat(M_PI)
        }
        // determine the orientation of the image and apply a transformation to the crop rectangle to shift it to the correct position
        var rectTransform: CGAffineTransform
        switch image.imageOrientation {
        case .Left:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -image.size.height)
        case .Right:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -image.size.width, 0)
        case .Down:
            rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -image.size.width, -image.size.height)
        default:
            rectTransform = CGAffineTransformIdentity
        }




        // adjust the transformation scale based on the image scale
        rectTransform = CGAffineTransformScale(rectTransform, UIScreen.mainScreen().scale, UIScreen.mainScreen().scale)
        // apply the transformation to the rect to create a new, shifted rect
        let transformedCropSquare = CGRectApplyAffineTransform(rect, rectTransform)
        // use the rect to crop the image
        let imageRef = CGImageCreateWithImageInRect(image.CGImage, transformedCropSquare)
        // create a new UIImage and set the scale and orientation appropriately
        let result = UIImage(CGImage: imageRef!, scale: image.scale, orientation: image.imageOrientation)

        return result
    }

Here are the functions to set and translate the mask view

    func setTopMask(){
        let path = CGPathCreateWithRect(cropViewMask.frame, nil)
        topMaskLayer.path = path
        topImageView.layer.mask = topMaskLayer

    }

    func translateMask(sender: UIPanGestureRecognizer) {
        let translation = sender.translationInView(self.view)
        sender.view!.center = CGPointMake(sender.view!.center.x + translation.x, sender.view!.center.y + translation.y)
        //        print(sender.translationInView(self.view))
        sender.setTranslation(CGPointZero, inView: self.view)
        //        print("panned mask")

        if sender.state == .Ended {
            printFrames()
        }

    }


  func setCropMaskFrame() {
        let x = ulCorner.center.x
        let y = ulCorner.center.y
        let width = urCorner.center.x - ulCorner.center.x
        let height = blCorner.center.y - ulCorner.center.y

        cropViewMask.frame = CGRectMake(x, y, width, height)
        setTopMask()
    }

Upvotes: 0

Views: 764

Answers (1)

Dusan Juranovic
Dusan Juranovic

Reputation: 177

I know this was long time ago...Just a thought, I ran into similar problem and what I found is that the frames for cropping are most probably correct. The problem lies in the actual size of the picture you're trying to crop. I solved the issue by aligning sizes of my view which holds the picture, with the actual picture size (in points). Then the cropping area cropped what was selected. I know this is probably not a solution, just sharing my experience, hope it helps to turn on some lightbulbs :)

Upvotes: 2

Related Questions