Обрезание изображения, захваченного AVCaptureSession
Я пишу приложение для iPhone, которое использует AVFoundation, чтобы сделать снимок и обрезать его.
Приложение похоже на считыватель QR-кода: он использует AVCaptureVideoPreviewLayer с наложением.
Наложение имеет квадрат. Я хочу обрезать изображение, чтобы обрезанное изображение было точно тем, что у пользователя есть места внутри квадрата.
Уровень предварительного просмотра имеет гравитацию AVLayerVideoGravityResizeAspectFill.
Похоже, что камера фактически захватывает не то, что видит пользователь в слое предварительного просмотра. Это означает, что мне нужно перейти от системы координат предварительного просмотра к системе координат захваченного изображения, чтобы я мог обрезать изображение. Для этого я считаю, что мне нужны следующие параметры:
1. соотношение между размером изображения и размером захваченного изображения.
2. информация, которая сообщает, какая часть захваченного изображения соответствует тому, что отображается на уровне предварительного просмотра.
Кто-нибудь знает, как я могу получить эту информацию, или если существует другой подход к обрезке изображения.
(p.s. захват снимка экрана предварительного просмотра не является вариантом, так как я понимаю, что это может привести к отказу приложения).
Заранее благодарю
Ответы
Ответ 1
Надеюсь, это соответствует вашим требованиям.
- (UIImage *)cropImage:(UIImage *)image to:(CGRect)cropRect andScaleTo:(CGSize)size {
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGImageRef subImage = CGImageCreateWithImageInRect([image CGImage], cropRect);
NSLog(@"---------");
NSLog(@"*cropRect.origin.y=%f",cropRect.origin.y);
NSLog(@"*cropRect.origin.x=%f",cropRect.origin.x);
NSLog(@"*cropRect.size.width=%f",cropRect.size.width);
NSLog(@"*cropRect.size.height=%f",cropRect.size.height);
NSLog(@"---------");
NSLog(@"*size.width=%f",size.width);
NSLog(@"*size.height=%f",size.height);
CGRect myRect = CGRectMake(0.0f, 0.0f, size.width, size.height);
CGContextScaleCTM(context, 1.0f, -1.0f);
CGContextTranslateCTM(context, 0.0f, -size.height);
CGContextDrawImage(context, myRect, subImage);
UIImage* croppedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRelease(subImage);
return croppedImage;
}
Ответ 2
вы можете использовать этот api из AVFoundation: AVMakeRectWithAspectRatioInsideRect
он вернет область обрезки для изображения в ограничивающей области, яблочный документ находится здесь:
https://developer.apple.com/library/ios/Documentation/AVFoundation/Reference/AVFoundation_Functions/Reference/reference.html
Ответ 3
Я думаю, что это просто, как этот
- (CGRect)computeCropRect:(CGImageRef)cgImageRef
{
static CGFloat cgWidth = 0;
static CGFloat cgHeight = 0;
static CGFloat viewWidth = 320;
if(cgWidth == 0)
cgWidth = CGImageGetWidth(cgImageRef);
if(cgHeight == 0)
cgHeight = CGImageGetHeight(cgImageRef);
CGRect cropRect;
// Only based on width
cropRect.origin.x = cropRect.origin.y = kMargin * cgWidth / viewWidth;
cropRect.size.width = cropRect.size.height = kSquareSize * cgWidth / viewWidth;
return cropRect;
}
с kMargin и kSquareSize (20 точек и 280 точек в моем случае) - это поле и область сканирования соответственно
Затем выполните обрезку
CGRect cropRect = [self computeCropRect:cgCapturedImageRef];
CGImageRef croppedImageRef = CGImageCreateWithImageInRect(cgCapturedImageRef, cropRect);