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

Отношение изображений iPhone к AVCaptureSession

Я использую исходный код для захвата изображения с помощью AVCaptureSession. Тем не менее, я обнаружил, что предварительный просмотр CaptureSessionManager - это дробитель, а затем окончательное снятое изображение. enter image description here

Я обнаружил, что приведенное изображение всегда имеет отношение 720x1280 = 9: 16. Теперь я хочу обрезать полученный образ на UIImage с соотношением 320: 480, чтобы он захватывал только часть, видимую в файле предварительного просмотра. Есть идеи? Большое спасибо.

Релевантные вопросы в stackoverflow (пока нет хорошего ответа): Q1, Q2

Исходный код:

- (id)init {
if ((self = [super init])) {
    [self setCaptureSession:[[[AVCaptureSession alloc] init] autorelease]];
}
return self;
}

- (void)addVideoPreviewLayer {
[self setPreviewLayer:[[[AVCaptureVideoPreviewLayer alloc] initWithSession:[self captureSession]] autorelease]];
[[self previewLayer] setVideoGravity:AVLayerVideoGravityResizeAspectFill];

}

- (void)addVideoInput {
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];   
if (videoDevice) {
    NSError *error;


    if ([videoDevice isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus] && [videoDevice lockForConfiguration:&error]) {
        [videoDevice setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
        [videoDevice unlockForConfiguration];
    }        

    AVCaptureDeviceInput *videoIn = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
    if (!error) {
        if ([[self captureSession] canAddInput:videoIn])
            [[self captureSession] addInput:videoIn];
        else
            NSLog(@"Couldn't add video input");     
    }
    else
        NSLog(@"Couldn't create video input");
}
else
    NSLog(@"Couldn't create video capture device");
}

- (void)addStillImageOutput 
{
  [self setStillImageOutput:[[[AVCaptureStillImageOutput alloc] init] autorelease]];
  NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey,nil];
  [[self stillImageOutput] setOutputSettings:outputSettings];

  AVCaptureConnection *videoConnection = nil;
  for (AVCaptureConnection *connection in [[self stillImageOutput] connections]) {
    for (AVCaptureInputPort *port in [connection inputPorts]) {
      if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
        videoConnection = connection;
        break;
      }
    }
    if (videoConnection) { 
      break; 
    }
  }

  [[self captureSession] addOutput:[self stillImageOutput]];
}

- (void)captureStillImage
{  
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in [[self stillImageOutput] connections]) {
    for (AVCaptureInputPort *port in [connection inputPorts]) {
        if ([[port mediaType] isEqual:AVMediaTypeVideo]) {
            videoConnection = connection;
            break;
        }
    }
    if (videoConnection) { 
  break; 
}
}

NSLog(@"about to request a capture from: %@", [self stillImageOutput]);
[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:videoConnection 
                                                   completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) { 
                                                     CFDictionaryRef exifAttachments = CMGetAttachment(imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);
                                                     if (exifAttachments) {
                                                       NSLog(@"attachements: %@", exifAttachments);
                                                     } else { 
                                                       NSLog(@"no attachments");
                                                     }
                                                     NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];    
                                                     UIImage *image = [[UIImage alloc] initWithData:imageData];
                                                     [self setStillImage:image];
                                                     [image release];
                                                     [[NSNotificationCenter defaultCenter] postNotificationName:kImageCapturedSuccessfully object:nil];
                                                   }];
}


Редактировать после проведения еще нескольких исследований и испытаний: Свойство AVCaptureSession "sessionPreset" имеет следующие константы: я не проверял каждый из них, но отметил, что большинство из них - либо 9:16, либо 3: 4,

  • NSString * const AVCaptureSessionPresetPhoto;
  • NSString * const AVCaptureSessionPresetHigh;
  • NSString * const AVCaptureSessionPresetMedium;
  • NSString * const AVCaptureSessionPresetLow;
  • NSString * const AVCaptureSessionPreset352x288;
  • NSString * const AVCaptureSessionPreset640x480;
  • NSString * const AVCaptureSessionPresetiFrame960x540;
  • NSString * const AVCaptureSessionPreset1280x720;
  • NSString * const AVCaptureSessionPresetiFrame1280x720;

В моем проекте у меня полноэкранный просмотр (размер кадра 320x480) также: [[self previewLayer] setVideoGravity: AVLayerVideoGravityResizeAspectFill];

Я сделал это следующим образом: сделайте снимок размером 9:16 и обрезайте его до 320: 480, точно видимую часть предварительного просмотра. Он отлично выглядит.

Часть кода для изменения размера и кручения для замены старым кодом

NSData *imageData = [AVCaptureStillImageOutput  jpegStillImageNSDataRepresentation:imageSampleBuffer];
 UIImage *image = [UIImage imageWithData:imageData]; 
UIImage *scaledimage=[ImageHelper scaleAndRotateImage:image];
 //going to crop the image 9:16 to 2:3;with Width fixed 
float width=scaledimage.size.width; 
float height=scaledimage.size.height; 
float top_adjust=(height-width*3/2.0)/2.0;  
[self setStillImage:[scaledimage croppedImage:rectToCrop]];
4b9b3361

Ответ 1

iPhone-камера изначально 4: 3. Полученные изображения 16: 9 уже обрезаны с 4: 3. Обрезание этих 16: 9 изображений снова до 4: 3 не то, что вы хотите. Вместо этого получите исходные изображения 4: 3 с камеры iPhone, установив self.captureSession.sessionPreset = AVCaptureSessionPresetPhoto (перед добавлением каких-либо входов/выходов в сеанс).