iPhone 6+(规模错误?)

时间:2016-04-07 07:01:20

标签: ios avcapturesession iphone-6-plus avcapturedevice uiscreen

我有一个iOS应用程序使用相机拍照。 它使用在屏幕上绘制的路径(CGPath)(例如矩形),并在该路径中拍摄照片。该应用仅支持纵向方向。

为了实现这一点,我使用:AVCaptureSessionAVCaptureStillImageOutputAVCaptureDeviceAVCaptureVideoPreviewLayer (我猜这些应用程序的开发人员都很熟悉。)

我的代码使用UIScreen.mainScreen().boundsUIScreen.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)。 那可能是什么问题?

2 个答案:

答案 0 :(得分:0)

我在应用中使用以下代码,它适用于6 +。

代码启动AVCaptureSession,从设备的摄像头提取视频输入。

在执行此操作时,它会从captureOutput委托函数不断更新runImage var。

当用户想要拍照时,会调用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 var。

-(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...

}

答案 1 :(得分:-1)

如果其他人有同样的问题。以下是让我出错的原因:

我正在命名一个文件:xyz@2x.png。

当UIScreen.mainScreen()。scale == 3.0(iPhone 6+的情况下) 它必须命名为:xyz@3x.png。