Подтвердить что ты не робот

Обрезание изображения, захваченного AVCaptureSession

Я пишу приложение для iPhone, которое использует AVFoundation, чтобы сделать снимок и обрезать его. Приложение похоже на считыватель QR-кода: он использует AVCaptureVideoPreviewLayer с наложением. Наложение имеет квадрат. Я хочу обрезать изображение, чтобы обрезанное изображение было точно тем, что у пользователя есть места внутри квадрата.

Уровень предварительного просмотра имеет гравитацию AVLayerVideoGravityResizeAspectFill.

Похоже, что камера фактически захватывает не то, что видит пользователь в слое предварительного просмотра. Это означает, что мне нужно перейти от системы координат предварительного просмотра к системе координат захваченного изображения, чтобы я мог обрезать изображение. Для этого я считаю, что мне нужны следующие параметры: 1. соотношение между размером изображения и размером захваченного изображения. 2. информация, которая сообщает, какая часть захваченного изображения соответствует тому, что отображается на уровне предварительного просмотра.

Кто-нибудь знает, как я могу получить эту информацию, или если существует другой подход к обрезке изображения.

(p.s. захват снимка экрана предварительного просмотра не является вариантом, так как я понимаю, что это может привести к отказу приложения).

Заранее благодарю

4b9b3361

Ответ 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;
}

Ответ 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);