Search code examples
iosswiftuiimagepickercontroller

UIImagePickerController picking bad quality images from Photo Library


I’m using normal tap gesture on ‘UIImageView’ when presenting an UIImagePickerController. But I don’t know why the images picked from Photo Library are always coming out to be bad quality(blurred, cropped etc.). When picking from Camera the images come out to be perfectly fine.

IMAGE FROM PHOTO LIBRARY

IMAGE FROM CAMERA

Here is complete code for this custom view class.

class ImageEditingView: UIView {

let imageView = UIImageView()

weak var delegate: ViewController!

var croppingRect: CGRect?
var croppedRect: CGRect?

var ratioWidth: CGFloat? {
    didSet {
        self.setNeedsDisplay()
    }
}
var ratioHeight: CGFloat? {
    didSet {
        self.setNeedsDisplay()
    }
}

// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
    super.draw(rect)
    // Drawing code

    let padding: CGFloat = 20

    self.imageView.frame = CGRect(center: rect.midPoint, size: rect.size - padding)
    self.imageView.contentMode = .scaleAspectFill
    self.imageView.clipsToBounds = true
    self.imageView.isUserInteractionEnabled = true
    self.imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(openImagePickerConroller)))
    self.addSubview(imageView)



    if let imageWidth = ratioWidth, let imageHeight = ratioHeight {
        if imageWidth > imageHeight {
            let newImageHeight = imageHeight/imageWidth * (rect.size.width - (2 * padding))
            let yForCroppedRect = (self.bounds.size.height - newImageHeight)/2
            self.croppingRect = CGRect(x: padding, y: yForCroppedRect, width: rect.size.width - (2 * padding), height: newImageHeight)
        } else if imageWidth < imageHeight {
            let newImageWidth = imageWidth/imageHeight * (rect.size.height - (2 * padding))
            let xForCroppedRect = (self.bounds.size.width - newImageWidth)/2
            self.croppingRect = CGRect(x: xForCroppedRect, y: padding, width: newImageWidth, height: rect.size.height - (2 * padding))
        } else {
            self.croppingRect = nil
        }
    }

    let bigRect = CGRect(x: 0, y: 0, width: self.bounds.width, height: self.bounds.height)
    let smallRect = self.croppingRect ?? self.imageView.frame
    self.croppedRect = smallRect
    let pathBigRect = UIBezierPath(rect: bigRect)
    let pathSmallRect = UIBezierPath(rect: smallRect)

    pathBigRect.append(pathSmallRect)
    pathBigRect.usesEvenOddFillRule = true

    let fillLayer = CAShapeLayer()
    fillLayer.path = pathBigRect.cgPath
    fillLayer.fillRule = CAShapeLayerFillRule.evenOdd
    fillLayer.fillColor = UIColor.darkGray.cgColor
    //fillLayer.opacity = 0.4
    self.layer.addSublayer(fillLayer)
}

@objc func openImagePickerConroller() {
    let imagePicker = UIImagePickerController()
    imagePicker.sourceType = .photoLibrary//.camera
    imagePicker.delegate = self
    self.delegate.present(imagePicker, animated: true, completion: nil)
}

}

extension ImageEditingView: UIImagePickerControllerDelegate, UINavigationControllerDelegate {

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    if let pickedImage = info[.originalImage] as? UIImage {
        self.imageView.image = pickedImage
        self.ratioWidth = 10
        self.ratioHeight = 10
        self.delegate.dismiss(animated: true, completion: nil)
    }
}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    self.delegate.dismiss(animated: true, completion: nil)
}

}

extension CGRect {
init(center: CGPoint, size: CGSize) {
    let origin = CGPoint(x: center.x - (size.width/2), y: center.y - (size.height/2))
    self.init(origin: origin, size: size)
}

var midPoint: CGPoint {
    return CGPoint(x: self.midX, y: self.midY)
}
}

extension CGSize {
static func -(size: CGSize, diff: CGFloat) -> CGSize {
    let dim = size.width <= size.height ? size.width : size.height
    return CGSize(width: dim - diff, height: dim - diff)
}
}

Solution

  • Are you testing on iOS 13.0 beta by any chance? Try it again with the latest iOS 13 beta, which should fix this bug.