2

I'm using a nice github plugin for Swift https://github.com/budidino/ShittyImageCrop responsible for cropping the image.

I need aspect ratio 4:3, so I call this controller like this:

let shittyVC = ShittyImageCropVC(frame: (self.navigationController?.view.frame)!, image: image!, aspectWidth: 3, aspectHeight: 4)
self.navigationController?.present(shittyVC, animated: true, completion: nil)

Now, when I provide horizontal image (wider than taller) - cropped result is fine - I see a photo with aspect ratio 4:3 as an output.

But when I provide vertical image and try to cropp it - I'm seeing tilted output. So for example, when normal photo is like this:

enter image description here

vertical - and tilted - one looks like this:

enter image description here

(sorry for low res here). Why does it get shifted to one side?

I suspect the problem might be somewhere in the logic of the crop-button:

func tappedCrop() {
print("tapped crop")

var imgX: CGFloat = 0
if scrollView.contentOffset.x > 0 {
  imgX = scrollView.contentOffset.x / scrollView.zoomScale
}

let gapToTheHole = view.frame.height/2 - holeRect.height/2
var imgY: CGFloat = 0
if scrollView.contentOffset.y + gapToTheHole > 0 {
  imgY = (scrollView.contentOffset.y + gapToTheHole) / scrollView.zoomScale
}

let imgW = holeRect.width  / scrollView.zoomScale
let imgH = holeRect.height  / scrollView.zoomScale

print("IMG x: \(imgX) y: \(imgY) w: \(imgW) h: \(imgH)")

let cropRect = CGRect(x: imgX, y: imgY, width: imgW, height: imgH)
let imageRef = img.cgImage!.cropping(to: cropRect)
let croppedImage = UIImage(cgImage: imageRef!)

var path:String = NSTemporaryDirectory() + "tempFile.jpeg"


if let data = UIImageJPEGRepresentation(croppedImage, 0.95) { //0.4 - compression quality
    //print("low compression is here")
    try? data.write(to: URL(fileURLWithPath: path), options: [.atomic])

}

self.dismiss(animated: true, completion: nil)
}
user3766930
  • 5,629
  • 10
  • 51
  • 104
  • 1
    Basically you're saying you're using code you don't understand, and when it doesn't work as you expect, you don't understand that either. Wouldn't this be a question for the author of the code you're using? – matt Nov 29 '16 at 01:30
  • @matt yes, that's correct :( the problem is that this repo seems to be abandoned for quite some time and I thought here would be a better place to ask for the root cause of this problem... Do you know what might be wrong in the code? I tried to change it by myself, but failed, at this moment even the smallest hint would be great for me – user3766930 Nov 29 '16 at 08:51
  • 1
    I'm not sure if this is the case for this code because I haven't done it with a scroll view, but I believe when you do `let croppedImage =` there is an orientation option. So you could try something alone the lines of `let croppedImage: UIImage = UIImage(CGImage: imageRef, scale: imageRef.scale, orientation: imageRef.imageOrientation)` Not sure if there is an original image you would want to reference the orientation of, but yeah, I would maybe try something along those lines? – Kayla Galway Nov 29 '16 at 15:55

1 Answers1

1

ShittyImageCrop saves cropped images directly to your album and I couldn't replicate your issue using vertical images.

I see you used UIImageJPEGRepresentation compared to UIImageWriteToSavedPhotosAlbum from ShittyImageCrop and it seems other people also have problems with image rotation after using UIImageJPEGRepresentation.

Look up iOS UIImagePickerController result image orientation after upload and iOS JPEG images rotated 90 degrees

EDIT

try implementing fixOrientation() from https://stackoverflow.com/a/27775741/611879

add fixOrientation():

func fixOrientation(img:UIImage) -> UIImage {
  if (img.imageOrientation == UIImageOrientation.Up) { 
    return img
  }

  UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale)
  let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
  img.drawInRect(rect)

  let normalizedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()
  UIGraphicsEndImageContext()
  return normalizedImage
}

and then do it before using UIImageJPEGRepresentation:

if let data = UIImageJPEGRepresentation(fixOrientation(croppedImage), 0.95) {
  try? data.write(to: URL(fileURLWithPath: path), options: [.atomic])
}

EDIT 2

please edit the init method of ShittyImageCrop by replacing img = image with:

if (image.imageOrientation != .up) {
  UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale)
  var rect = CGRect.zero
  rect.size = image.size
  image.draw(in: rect)
  img = UIGraphicsGetImageFromCurrentImageContext()
  UIGraphicsEndImageContext()
} else {
  img = image
}
Community
  • 1
  • 1
budiDino
  • 13,044
  • 8
  • 95
  • 91
  • Thank you for a quick reply! Well you are completely right, the problem on my site seems to be with using `UIImageJPEGRepresentation`. I uploaded my photo to your project on github and it works nice! The reason why I'm using `UIImageJPEGRepresentation` instead of `UIImageWriteToSavedPhotosAlbum` proposed by you is because I need to get the url path of the image for further processing... Is there any way I could get this url while using `UIImageWriteToSavedPhotosAlbum`? – user3766930 Nov 29 '16 at 16:18
  • @user3766930 I've updated the answer but didn't actually test it out. I guess you need to rotate the image before saving it to file. You should test a few of the answers to the questions I've linked above. – budiDino Nov 29 '16 at 17:54
  • I noticed that problem still exists in my case when I use photos taken from the front camera on the iphone, even though I used your function for fixing the orientation, now it still saves the image to photos tilted :( – user3766930 Nov 29 '16 at 19:27
  • @user3766930 sorry for a super late reply but life happened to me so I had to postpone helping you. I took some time and finally figured out what is the issue. I've updated my answer and hopefully I'll updated the ShittyImageCrop project too. Thank you for making me improve the control ;) – budiDino Dec 29 '16 at 13:53