読者です 読者をやめる 読者になる 読者になる

【swift】iPadでUIImagePickerControllerを使ってフォトライブラリから画像を読み込むとトリミングがおかしい

iPadで、UIImagePickerControllerを使う時、なんかトリミングがおかしくなる。

sourceType を UIImagePickerControllerSourceType.camera (カメラ) にすると、問題はないけど、

sourceType を UIImagePickerControllerSourceType.photoLibrary (フォトライブラリ) にすると、写真が小さい状態で表示されてトリミングが思った通りにいかない。

これはiPadでの問題かもしれない。iPhoneでは問題はなかったので。

同じような問題を他の方も言っている。

なので、オリジナルでトリミングする機能を作ることにしました。

と思ったら、それを作っている方がいました。

これを流用させていただくことにしました。

これはswift ファイルのクラスを objective-c で呼んでいたので、そこだけswift3 で呼ぶようにしました。

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

    var image:UIImage = info[UIImagePickerControllerOriginalImage]  as! UIImage
    //let image:UIImage = info[UIImagePickerControllerEditedImage]  as! UIImage
    image = self.imageByScalingToMaxSize(sourceImage: image)

    picker.dismiss(animated: false, completion: nil)

    let imgCropperVC:DRImageCropperViewController = DRImageCropperViewController()
    imgCropperVC.originalImage = image
    imgCropperVC.cropFrame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.width)
    imgCropperVC.limitRatio = 3.0
    imgCropperVC.delegate = self
    present(imgCropperVC, animated: false, completion: nil)
}

func imageCropper(_ cropperViewController:DRImageCropperViewController, didFinished editImg:UIImage){

    btnImg.setImage(editImg, for: .normal)

    let imageData:NSData? = UIImagePNGRepresentation(editImg) as NSData?

    let key:String = "img" + String(currentIndex)
    userDefaults.set(imageData, forKey: key)
    userDefaults.synchronize()

    cropperViewController.dismiss(animated: true, completion: nil)

}

func imageCropperDidCancel(_ cropperViewController:DRImageCropperViewController){
    cropperViewController.dismiss(animated: true, completion: nil)
}

func imageByScalingToMaxSize(sourceImage:UIImage)->UIImage{
    if (sourceImage.size.width < ORIGINAL_MAX_WIDTH) {
        return sourceImage
    }
    var btWidth:CGFloat = 0.0
    var btHeight:CGFloat = 0.0

    if (sourceImage.size.width > sourceImage.size.height) {
        btHeight = ORIGINAL_MAX_WIDTH
        btWidth = sourceImage.size.width * (ORIGINAL_MAX_WIDTH / sourceImage.size.height)
    }else{
        btWidth = ORIGINAL_MAX_WIDTH
        btHeight = sourceImage.size.height * (ORIGINAL_MAX_WIDTH / sourceImage.size.width)
    }

    let targetSize:CGSize = CGSize(width: btWidth, height: btHeight)
    return self.imageByScalingAndCroppingForSourceImage(sourceImage: sourceImage, targetSize:targetSize)
}

func imageByScalingAndCroppingForSourceImage(sourceImage:UIImage,targetSize:CGSize)->UIImage{
    var newImage:UIImage? = nil
    let imageSize:CGSize = sourceImage.size
    let width:CGFloat = imageSize.width
    let height:CGFloat = imageSize.height
    let targetWidth:CGFloat = targetSize.width
    let targetHeight:CGFloat = targetSize.height
    var scaleFactor:CGFloat = 0.0
    var scaledWidth:CGFloat = targetWidth
    var scaledHeight:CGFloat = targetHeight
    var thumbnailPoint:CGPoint = CGPoint(x:0.0,y:0.0)

    if (imageSize.equalTo(targetSize) == false){
        let widthFactor:CGFloat = targetWidth / width
        let heightFactor:CGFloat = targetHeight / height

        if (widthFactor > heightFactor){
            scaleFactor = widthFactor; // scale to fit height
        }else{
            scaleFactor = heightFactor; // scale to fit width
            scaledWidth  = width * scaleFactor
            scaledHeight = height * scaleFactor
        }

        if (widthFactor > heightFactor){
            thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5
        }else{
            if (widthFactor < heightFactor){
                thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5
            }
        }

    }

    UIGraphicsBeginImageContext(targetSize); // this will crop
    var thumbnailRect:CGRect = CGRect.zero

    thumbnailRect.origin = thumbnailPoint
    thumbnailRect.size.width  = scaledWidth
    thumbnailRect.size.height = scaledHeight

    sourceImage.draw(in: thumbnailRect)

    newImage = UIGraphicsGetImageFromCurrentImageContext()
    if(newImage == nil) {
        print("could not scale image")
    }

    UIGraphicsEndImageContext()
    return newImage!

}