捕获AVFoundation中的缩放预览视图

时间:2011-11-16 10:29:49

标签: iphone ios uiview avfoundation

我在AVFoundation相机中使用缩放功能,我通过缩放具有AVCaptureVideoPreviewLayer的视图实现了缩放。        现在我想捕捉缩放的图像。

这是我的代码,用于添加AVFoundationVideoPreviewLayer以查看:

 // create a uiview subclass for showing the camera feed
 UIView *previewView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 430)];
 [[self view] addSubview:previewView];

 CGRect layerRect = CGRectMake(0, 0, 320, 430);
 [[self avCaptureVideoPreviewLayer] setBounds:layerRect];

 [[self  previewLayer] setPosition:CGPointMake(CGRectGetMidX(layerRect), CGRectGetMidY(layerRect))];

 // add the video previewview layer to the preview view
 [[previewView layer] addSublayer:[self avCaptureVideoPreviewLayer]];

用于缩放预览视图的代码

  // zoom the preview view using core graphics
 [previewView setTransform:CGAffineTransformMakeScale(2.0, 2.0 )];

现在我想从previewView

捕获这个缩放的图像

提前致谢。

4 个答案:

答案 0 :(得分:7)

最后,我设法在我的应用中添加捕获缩放的照片。它有点难看,但它的工作原理。我使用UIImage +来自网络的调整大小代码,然后将图像缩放到缩放比例,并计算缩放区域的偏移位置[在摄像机视图中可见]然后我裁剪它。

现在我的应用程序有时会在缩放比例达到最大值时崩溃,即6倍。我收到内存问题,因为缩放的图像太大,我会问这是另一个问题。

希望这段代码可能对某人有用。

 if (cameraZoom > 1.0) 
 {
        // save the images original size
        CGSize orgSize = [image size];  

        // resize the image to the zoom scale  
        image = [image resizedImage:CGSizeMake(image.size.width * cameraZoom, image.size.height *cameraZoom) interpolationQuality:kCGInterpolationNone];           

        // now calculate the offset x and offset y
        CGFloat offsetX = ( image.size.width / 2 ) - (orgSize.width /2) ;
        CGFloat offsetY =  ( image.size.height / 2 ) - (orgSize.height /2);

         // crop the image from the offset position to the original width and height
         image = [image croppedImage:CGRectMake(offsetX, offsetY, orgSize.width, orgSize.height)];
    }


    UIButton *imgBtn = (UIButton *)[self.view viewWithTag:500];
    [imgBtn setImage:image forState:UIControlStateNormal];

答案 1 :(得分:4)

我正在设置图像比例并直接裁剪:

AVCaptureConnection *stillImageConnection = [_stillImageOutput.connections objectAtIndex:0];
[stillImageConnection setVideoScaleAndCropFactor:imagePreviewScale];

它应该仅适用于视频连接,但对于静态图像也可以像魅力一样。

答案 2 :(得分:2)

你应该首先尝试裁剪然后调整大小,这样你就不会记忆问题。

你现在正在做的是: 当6x时600X600图像将变为3600X3600,然后你裁剪它,这将再次给600X600。 但是,为什么不尝试使用6x的600x600给100X100,然后再将其调整为600X600。

如果原始分辨率低,则两个过程的输出图像可能略有不同,但如果原始分辨率为8MP / 5MP / 3MP(最高为5 / 4s / 4 / 3G),那么输出将几乎相似。

因此,为了获得更好的结果,请在低分辨率和高分辨率时使用您的处理,使用我上面建议的反向处理。

答案 3 :(得分:0)

我能够先完成裁剪,然后使用核心图形图像变换进行缩放。请注意,我们将原始图像大小和比例保留在图像缓冲区中,并通过对各个像素的变换操作完全执行缩放功能。请注意,此代码没有考虑设备方向(在我的情况下,我目前只使用纵向直立),但可以通过额外的旋转变换轻松完成:

UIGraphicsBeginImageContextWithOptions(imageSize,NO,1.0); // this will crop

CGContextRef context = UIGraphicsGetCurrentContext();


CGRect newRect = CGRectMake(0, 0, width, height);

// apply a scaling transform to zoom
// rotate about the center
// First we scale, then rotate, then translate
// actual matrix multiplication steps are applied in reverse when using
// right-handed coordinate system
// M' = M * translatation * rotation * scale
CGContextTranslateCTM(context, (width - scaledWidth)*0.5f,
                               (height-scaledHeight)*0.5f);
CGContextScaleCTM(context,scaleFactor,scaleFactor);

[sourceImage drawInRect:newRect];

newImage = UIGraphicsGetImageFromCurrentImageContext();
if (newImage == nil) {
    NSLog(@"could not scale image");
}

// pop the context to get back to the default
UIGraphicsEndImageContext();