0

The problem I am facing is that the image taken from the camera is larger then the one shown in the live view. I have the camera view setup as Aspect Fill.

So the image that I get from the camera is about 4000x3000 and the view that shows the live feed from the camera is 375x800 (fullscreen iPhoneX size) so how do I transform/cut out part of the image from the image gotten from the camera to be the same as the one shown in the live view, so I can further manipulate the image (draw over it).

As far as I understand the Aspect Fill property clips the image that cannon't be shown in the view. But that clip does not happen on X = 0 and y = 0 it happens somewhere in the middle of the image. So how do i get that X and Y on the original image so that i can crop out exactly that part out.

I hope I explained well enough.

EDIT:

To give more context and some code snipets to make it easier to understand the issue.

Setting up my camera with the .resizeAspectFill gravity.

cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
    cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait
    cameraPreviewLayer?.frame = self.captureView.frame
    self.captureView.layer.addSublayer(cameraPreviewLayer!)

which is displayed in the live view (captureView) that has the size of 375x818 (width: 375 and height: 818).

Then I get the image from that camera on button click and the size of that image is:

3024x4032 (width: 3024 and height: 4032)

So what i want to do is crop the image from the camera to be the same as the one in the live view (captureView) that is set to AspectFill type.

1 Answers1

0

As you already state, content mode option Aspect fill tries to fill up the live view and you are also right that it crops some rectangle from center (cropping top-bottom or left-right depending upon the image size and the image view size)

For generic solution there are two possible case

  1. The image needed to be cropped along the height to fit the image view (proportional drawing height is smaller)
  2. The image needed to be cropped along the width to fit the image view (proportional drawing width is smaller)

Considering your size notation is 4000x3000 (height = 4000, width = 3000 a portrait image) and your drawing canvas size is 375X800 (height = 375, width = 800), then your cropping would be height wise while setting the content mode Aspect Fill.

So cropping will be done from X=0 but the Y would be somewhat positive. So lets calculate the Y

let propotionalHeight = 4000 / 3000 * 800
let allowedHeight = 375
let topBottomCroppedHeight = proportionalHeight - allowedHeight
let croppedYPosition = topBottomCroppedHeight / 2

So here you got your Y value. and the height would be the height of the canvas / live view where you are rendering. Please replace these values with your variables.

If you are interested in how all the contentMode works can dive into here. All the contentMode supported by UIImageView is simulated here.

Happy coding.

UPDATE

one thing i forgot to mention that, this calculated croppedYPosition is for smaller proportion image. If you want to use this value for the original 4000X3000 image you have to scale this up for the original value as following

let originalYPosition = (croppedYPosition / 375) * 4000

Use originalYPosition to crop from the original image of size 4000X3000.

Ratul Sharker
  • 7,484
  • 4
  • 35
  • 44
  • the height and the width are switched. 3024x4032 (width: 3024 and height: 4032) for the image i get from the camera and 375x818 (width: 375 and height: 818) for the live view. – Klemen Andrašič Oct 23 '18 at 15:59
  • These are just values for understanding the concept, feel free to replace this with your variables. @KlemenAndrašič – Ratul Sharker Oct 23 '18 at 16:04
  • @KlemenAndrašič i forgot to mention that, if you want to crop from original image, you have to scale up the `croppedYPosition` for original image size. I have updated the question according to that. – Ratul Sharker Oct 23 '18 at 16:38