Обрезать изображение на квадрат в соответствии с размером UIView/CGRect

У меня есть реализация AVCaptureSession, и моя цель состоит в том, чтобы пользователь мог сделать снимок и сохранить только часть изображения на границе красного квадрата, как показано ниже:

UIViewController with an implementation of AVCaptureSession

AVCaptureSession previewLayer (камера) охватывает от (0,0) (вверху слева) до нижней части панели управления камерой (панель над надписью, которая содержит затвор). Моя панель навигации и панель управления полупрозрачны, поэтому камера может показывать.

Я использую [captureSession setSessionPreset:AVCaptureSessionPresetPhoto];, чтобы гарантировать, что исходное изображение, сохраненное в рулоне камеры, похоже на камеру Apple.

Пользователь сможет снимать фотографию в портретном, левом и правом левом, поэтому метод обрезки должен учитывать это.

До сих пор я пытался обрезать исходное изображение с помощью этого кода:

DDLogVerbose(@"%@: Image crop rect: (%f, %f, %f, %f)", THIS_FILE, self.imageCropRect.origin.x, self.imageCropRect.origin.y, self.imageCropRect.size.width, self.imageCropRect.size.height);

// Create new image context (retina safe)
UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.imageCropRect.size.width, self.imageCropRect.size.width), NO, 0.0);

// Create rect for image
CGRect rect = self.imageCropRect;

// Draw the image into the rect
[self.captureManager.stillImage drawInRect:rect];

// Saving the image, ending image context
UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();

Однако, когда я смотрю на обрезанное изображение в рулоне камеры, кажется, что он просто раздавил исходное изображение и не отбрасывал верхнюю и нижнюю части изображения, как хотелось бы. Это также приводит к 53 пикселям белого пространства в верхней части "обрезанного" изображения, вероятно, из-за положения y моего CGRect.

Это мой вывод журнала для CGRect:

 Image crop rect: (0.000000, 53.000000, 320.000000, 322.000000)

Здесь также описывается рамка красноватого вида в супервизии.

Есть ли что-то важное, что я пропускаю?

P.S. Исходный размер изображения (снятый камерой в портретном режиме):

Original image size: (2448.000000, 3264.000000)

Ответ 1

Вы можете обрезать изображения с помощью CGImageCreateWithImageInRect:

CGImageRef imageRef = CGImageCreateWithImageInRect([uncroppedImage CGImage], bounds);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);

Ответ 2

Не забудьте добавить параметр масштаба, иначе вы получите изображение с низким разрешением

CGImageRef imageRef = CGImageCreateWithImageInRect([uncroppedImage CGImage], CGRectMake(0, 0, 30, 120));
[imageView setImage:[UIImage imageWithCGImage:imageRef scale:[[UIScreen mainScreen] scale] orientation:UIImageOrientationUp]];
CGImageRelease(imageRef);

Ответ 3

Swift 3:

let imageRef:CGImage = uncroppedImage.cgImage!.cropping(to: bounds)!
let croppedImage:UIImage = UIImage(cgImage: imageRef)