0

У меня есть приложение iOS, использующее камеру для съемки. Он использует дорожку (CGPath), нарисованную на экране (например, прямоугольник), и она берет фотографию в этом пути. Приложение поддерживает только портретную ориентацию.iPhone 6+ (неправильная шкала?)

Для того чтобы это произошло я использую: AVCaptureSession, AVCaptureStillImageOutput, AVCaptureDevice, AVCaptureVideoPreviewLayer (я думаю, все знакомы разработчикам делает этот вид приложений).

В моем коде используются UIScreen.mainScreen().bounds и UIScreen.mainScreen().scale, чтобы адаптироваться к различным устройствам и выполнять свою работу.

Все идет хорошо (на iPhone 5, iPhone 6), пока я не попробую приложение на iPhone 6+ (под управлением iOS 9.3.1) и не увижу, что что-то не так. Снимок сделан не в нужном месте.

У меня был кто-то на iPhone 6+, и, разместив соответствующее сообщение, я смог подтвердить, что это (UIScreen.mainScreen().scale) - это то, что он будет: 3.0. Я поместил правильные изображения запуска (640 × 960, 640 × 1136, 750 × 1334, 1242 × 2208) в проект. Так что может быть проблемой?

+1

Если у вас есть git, я взгляну на 6+ –

ответ

-1

В случае, если кто-то имеет тот же вопрос. Вот что заставило меня пойти не так:

Я назвал файл: [email protected]

Когда UIScreen.mainScreen(). Scale == 3.0 (случай iPhone 6+) его нужно называть: [email protected]

+0

Вам не нужно использовать расширения 2x и 3x для ваших изображений - я никогда их не использую, это так много хлопот. Просто возьмите самое большое изображение и позвольте устройству масштабировать его для вас, например. bigImage.png помещается в UIImageView с contentMode AspectFill. Меньшая головная боль. –

+0

Я не знаю, должен ли я это делать. Но я знаю, что когда я называет файл x. @ 2x.png во всех случаях, произошла ошибка, и когда я называю значение UIScreen.mainScreen(), оно работает. И позволить шкале устройства это не то, что вы хотите во всех возможных случаях. То же самое вы не обязательно должны иметь несколько изображений, чтобы выбрать самый большой. В любом случае, если вы говорите, вы можете избежать использования нескольких расширений, что лучше. – Michel

0

Я использую код ниже в приложении, он работает на 6+.

Код запускает AVCaptureSession, вытягивая видеовход с камеры устройства.

При этом он непрерывно обновляет runImage var из функции captureOutput delegate.

Когда пользователь хочет сделать снимок, вызывается метод takePhoto. Этот метод создает временное представление UIImageview и передает в него runImage. Этот временный UIImageView затем используется для рисования другой переменной, называемой currentImage, в масштабе устройства.

CurrentImage, в моем случае, квадратный, соответствующий рамке previewHolder, но я полагаю, вы можете сделать все, что захотите.

Объявите это: сканер

AVCaptureDevice * device; 
AVCaptureDeviceInput * input; 
AVCaptureVideoDataOutput * output; 
AVCaptureSession * session; 
AVCaptureVideoPreviewLayer * preview; 
AVCaptureConnection * connection; 
UIImage * runImage; 

нагрузки:

-(void)loadScanner 
{ 

    device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil]; 
    output = [AVCaptureVideoDataOutput new]; 
    session = [AVCaptureSession new]; 

    [session setSessionPreset:AVCaptureSessionPresetPhoto]; 
    [session addInput:input]; 
    [session addOutput:output]; 

    [output setSampleBufferDelegate:self queue:dispatch_get_main_queue()]; 
    [output setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]]; 

    preview = [AVCaptureVideoPreviewLayer layerWithSession:session]; 
    preview.videoGravity = AVLayerVideoGravityResizeAspectFill; 
    preview.frame = previewHolder.bounds; 

    connection = preview.connection; 
    [connection setVideoOrientation:AVCaptureVideoOrientationPortrait]; 
    [previewHolder.layer insertSublayer:preview atIndex:0]; 

} 

Продолжающееся захвата изображения, обновления runImage вар.

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection 
{ 

    runImage = [self imageForBuffer:sampleBuffer]; 

} 

Связано с выше.

-(UIImage *)imageForBuffer:(CMSampleBufferRef)sampleBuffer 
{ 

    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    CVPixelBufferLockBaseAddress(imageBuffer, 0); 
    void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); 
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
    size_t width = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer); 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
    CGImageRef quartzImage = CGBitmapContextCreateImage(context); 
    CVPixelBufferUnlockBaseAddress(imageBuffer,0); 
    CGContextRelease(context); 
    CGColorSpaceRelease(colorSpace); 
    UIImage *image = [UIImage imageWithCGImage:quartzImage]; 
    CGImageRelease(quartzImage); 

    UIImage * rotated = [[UIImage alloc] initWithCGImage:image.CGImage scale:1.0 orientation:UIImageOrientationRight]; 

    return rotated; 
} 

На тейк фото:

-(void)takePhoto 
{ 

    UIImageView * temp = [UIImageView new]; 
    temp.frame = previewHolder.frame; 
    temp.image = runImage; 
    temp.contentMode = UIViewContentModeScaleAspectFill; 
    temp.clipsToBounds = true; 
    [self.view addSubview:temp]; 

    UIGraphicsBeginImageContextWithOptions(temp.bounds.size, NO, [UIScreen mainScreen].scale); 
    [temp drawViewHierarchyInRect:temp.bounds afterScreenUpdates:YES]; 
    currentImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    [temp removeFromSuperview]; 

    //further code... 

} 
+0

Зачем вам нужен код? Просьба представить описание вашего кода и почему оно решит проблему пользователей. – Popeye

+0

@Popeye обновлено с дальнейшим объяснением; независимо от того, помогает ли он пользователю, я не знаю, что он будет делать, но я не видел никаких проблем с ним 6+ (если это даже проблема, мы не можем сказать точно). –

+0

Я смотрю ваш код. Попытка увидеть, как он отличается от моего. Помимо моего пребывания в Swift, я уже вижу несколько вариантов. Вы используете 'AVCaptureVideoDataOutput', я использую' AVCaptureStillImageOutput'; вы используете 'AVCaptureSessionPresetPhoto', я использую' AVCaptureSessionPresetHigh' ..etc .. Я полагаю, это не должно быть проблемой. С другой стороны, 'AVLayerVideoGravityResizeAspectFill' и' AVCaptureVideoOrientationPortrait', которые вы используете, и я не могу изменить ситуацию. Для 'imageForBuffer' я использую код, который я нашел здесь: developer.apple.com/library/ios/documentation/AudioVideo/ Я все еще должен смотреть дальше. – Michel

 Смежные вопросы

  • Нет связанных вопросов^_^