2013-04-22 3 views
3

Для приложения, которое я разрабатываю, я позволяю пользователю указывать размеры объекта, который они хотят захватить на камеру (например, 30 "x 40"). Следующее, что я хочу сделать, - показать канал камеры с помощью камерыOverlayView поверх нее, показывая только гладкий прозрачный квадрат, который имеет правильное соотношение для захвата этого объекта.Вырезание предопределенной части фотографии с камеры

Так что я попробовал 2 вещи, чтобы получить эту работу:

Используйте UIViewController, который использует AVCaptureVideoPreviewLayer для отображения представления с живым кормом видео. В верхней части этого канала я показываю прозрачный вид, который рисует квадрат с правильными размерами (с использованием отношения, указанного пользователем).

и

В очередной попытке я создал UIViewController, содержащий кнопку, которая всплывает UIImagePickerController. Используя этот контроллер, я также создал представление, которое я прикрепляю к сборщику, используя свойство cameraOverlayView.

Основная проблема, с которой я сталкиваюсь в обоих этих методах, состоит в том, что изображение, которое на самом деле захвачено, всегда больше, чем то, что я вижу на экране, но я не совсем уверен, как вырезать ЭТО часть изображения после фотография сделана.

Так, например: Отображается мой UIImagePickerController, я накладываю надпись поверх того, что показывает квадрат размером 300 x 400 пикселей. Пользователь использует этот квадрат, чтобы сделать снимок своего объекта и центрирует свой объект внутри этого квадрата.

Снимок сделан, но вместо картины, которая является 320x480 (или 640x960) я получаю результат, 3500x2400 (или что-то в этом роде. Это совершенно другое отношение, то соотношение экрана (конечно).

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

Код, который фактически вычисляет размер квадрата, который должен быть показан (и должен использоваться для определения того, какая часть изображения должна быть разрез):

+ (CGRect) getFrameRect:(CGRect) rect forSize:(CGSize) frameSize { 
    if (CGSizeEqualToSize(frameSize, CGSizeZero)) 
     return CGRectZero; 

    float maxWidth = rect.size.width - 20; 
    float maxHeight = rect.size.height - 20; 

    float ratioX = maxWidth/frameSize.width; 
    float ratioY = maxHeight/frameSize.height; 
    float ratio = MIN(ratioX, ratioY); 

    float newWidth = frameSize.width * ratio; 
    float newHeight = frameSize.height * ratio; 

    float x = (rect.size.width - newWidth)/2; 
    float y = (rect.size.height - newHeight)/2; 

    return CGRectMake(x, y, newWidth, newHeight); 
} 

Это определяет наибольший квадрат, который может быть создан с отношением, указанным в параметре frameSize, с размерами, в которых квадрат должен быть нарисован в параметре rect.

Некоторые решения приходят на ум, но я не уверен, что это выполнимо.

  • Уменьшить фотографию до ширины и высоты экрана (независимо от того, что на первом месте), взять центр изображения и тот же центр, который отображается при съемке? Не уверен, что это сработает, я попробовал это немного, но это не удалось.

ответ

3

Хорошо, я нашел решение:

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

Когда ваше устройство iOS находится в портретном режиме, высота фотографии уменьшена до высоты экрана, и отображаются только средние 640px.

enter image description here

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

После этого я вырезал средние 640x960 пикселей, чтобы получить то же изображение, которое было показано при съемке.

После этого координаты моего прямоугольного наложения такие же, как с моим наложением.

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 
    [picker dismissModalViewControllerAnimated:YES]; 

    UIImage* artImage = [info objectForKey:UIImagePickerControllerOriginalImage]; 


    CGFloat imageHeightRatio = artImage.size.height/960; 
    CGFloat imageWidth = artImage.size.width/imageHeightRatio; 

    CGSize newImageSize = CGSizeMake(imageWidth, 960); 
    artImage = [artImage imageByScalingProportionallyToSize:newImageSize]; 

    CGRect cutOutRect = CGRectMake((artImage.size.width/2) - (640/2), 0, 640, 960); 

    artImage = [self imageByCropping:artImage toRect:cutOutRect]; 

    CGRect imageCutRect = [FrameSizeCalculations getFrameRect:CGRectMake(0,0, artImage.size.width, artImage.size.height) forSize:self.frameSize]; 
    artImage = [self imageByCropping:artImage toRect:imageCutRect]; 

    CGRect imageViewRect = CGRectInset(_containmentView.bounds, 10, 10); 

    NSLog(@"ContainmentView: %f x %f x %f x %f", 
      _containmentView.frame.origin.x, 
      _containmentView.frame.origin.y, 
      _containmentView.frame.size.width, 
      _containmentView.frame.size.height 
     ); 

    NSLog(@"imageViewRect: %f x %f x %f x %f", 
      imageViewRect.origin.x, 
      imageViewRect.origin.y, 
      imageViewRect.size.width, 
      imageViewRect.size.height 
     ); 

    _imageView.frame = [FrameSizeCalculations getFrameRect:imageViewRect forSize:self.frameSize]; 

    NSLog(@"imageViewRect: %f x %f x %f x %f", 
      _imageView.frame.origin.x, 
      _imageView.frame.origin.y, 
      _imageView.frame.size.width, 
      _imageView.frame.size.height 
     ); 

    _imageView.contentMode = UIViewContentModeScaleAspectFill; 
    _imageView.image = artImage; 
} 
Смежные вопросы