0

I hate to say that I'm the new guy to iOS development but the shoe fits... My app needs to either load an image/capture one from camera (which it does) but then needs to crop in LANDSCAPE.

I now have an extension that takes the image and shrinks it down to a landscape image (looks good if the camera is taken from landscape position OR scrunches it to a landscape if taken in portrait). It places it in my "viewfinder" as a tiny landscape image (seen below) and I can swipe outward to make it the size of the "view finder" but that's not what I need.

enter image description here

(the "viewfinder" I had to draw because I didn't put borders on it but you can see the thumbnail in the top left)

func imagePickerController(_ picker: UIImagePickerController,
   didFinishPickingMediaWithInfo info: [String : Any]) {

        setImageToCrop(image: info[UIImagePickerControllerOriginalImage] as!
UIImage)

        picker.dismiss(animated: true, completion: nil)
    }

// -------------

func setImageToCrop(image:UIImage){
    imageView.image = image
    imageViewWidth.constant = image.size.width
    imageViewHeight.constant = image.size.height
    let scaleHeight = scrollView.frame.size.width/image.size.width
    let scaleWidth = scrollView.frame.size.height/image.size.height
    scrollView.minimumZoomScale = max(scaleWidth, scaleHeight)
    scrollView.zoomScale = max(scaleWidth, scaleHeight)

    self.cropButton.isHidden = false
}
// ------------------
@IBAction func cropButtonPressed(_ sender: Any) {
    let scale:CGFloat = 1/scrollView.zoomScale
    let x:CGFloat = scrollView.contentOffset.x * scale
    let y:CGFloat = scrollView.contentOffset.y * scale
    let width:CGFloat = scrollView.frame.size.width * scale
    let height:CGFloat = scrollView.frame.size.height * scale
    let croppedCGImage = imageView.image?.cgImage?.cropping(to: CGRect(x: x, y: y, width: width, height: height))
    let croppedImage = UIImage(cgImage: croppedCGImage!)

    // "now you can use croppedImage as you like...."


    setImageToCrop(image: croppedImage)

}
// ---------------

And then the extension that shrinks the image...

public extension UIImage {

/// Extension to fix orientation of an UIImage without EXIF
func fixOrientation() -> UIImage {

    guard let cgImage = cgImage else { return self }

    if imageOrientation == .up { return self }

    var transform = CGAffineTransform.identity

    switch imageOrientation {

    case .down, .downMirrored:
        transform = transform.translatedBy(x: size.width, y: size.height)
        transform = transform.rotated(by: CGFloat(M_PI))

    case .left, .leftMirrored:
        transform = transform.translatedBy(x: size.width, y: 0)
        transform = transform.rotated(by: CGFloat(M_PI_2))

    case .right, .rightMirrored:
        transform = transform.translatedBy(x: 0, y: size.height)
        transform = transform.rotated(by: CGFloat(-M_PI_2))

    case .up, .upMirrored:
        break
    }

    switch imageOrientation {

    case .upMirrored, .downMirrored:
        transform.translatedBy(x: size.width, y: 0)
        transform.scaledBy(x: -1, y: 1)

    case .leftMirrored, .rightMirrored:
        transform.translatedBy(x: size.height, y: 0)
        transform.scaledBy(x: -1, y: 1)

    case .up, .down, .left, .right:
        break
    }

    if let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, space: cgImage.colorSpace!, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) {

        ctx.concatenate(transform)

        switch imageOrientation {

        case .left, .leftMirrored, .right, .rightMirrored:
            ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.height, height: size.width))

        default:
            ctx.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
        }

        if let finalImage = ctx.makeImage() {
            return (UIImage(cgImage: finalImage))
        }
    }

    // something failed -- return original
    return self
}

}

I have been around and around with different answers in StackOverFlow but haven't found the solution I'm looking for. I first found an extension that was the "fix all holy grail" but it did nothing. (The app still crops the image but stil rotates when it's saved.)

I'm 100% sure it's something stupid/small that I'm missing but I'm now lost in my code and if it means anything, I've been chasing this issue for WEEKS, if not MONTHS, now. I didn't want to ask unless I absolutely had to. Is there a better way to get an image and crop it it landscape without having it rotate? or is there a fix to this code?

  • Show how you are saving it. If you save it as PNG it will discard the image orientation. If you save it as JPG it will keep the orientation info. If you really need to save your image as uncompressed PNG data you need redraw your image before saving it. https://stackoverflow.com/questions/42098390/swift-png-image-being-saved-with-incorrect-orientation/42098812?s=2|46.6563#42098812 – Leo Dabus Oct 26 '17 at 08:01
  • I'm assuming it's JPEG.. it doesn't really specify in the code, it just uses whatever from the camera uses – Bradley Carter Oct 26 '17 at 08:48

0 Answers0