2011-11-16 57 views
9

我正在使用AVFoundation摄像头中的缩放功能,我通过缩放具有AVCaptureVideoPreviewLayer的视图来实现缩放。 现在我想捕捉缩放图像。在AVFoundation中捕捉缩放预览视图

这里是我加入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捕获该缩放图像中提前

谢谢。

回答

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]; 
+0

还有其他更好的解决方案吗? – kadungon

+1

关于你的崩溃:简单地先裁剪而不是调整大小来解决你的内存问题。如果您稍后放弃大部分图像,请勿计算大图像。 – CipherCom

+0

我试过你的代码,但我无法弄清楚cameraZoom和最终结果总是只是空白图像。你能分享更多吗? –

2

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

你现在正在做的是: 600X600图像将变为3600X3600 6X时,那么你裁剪它,这将再次给600X600。 但是,为什么不尝试600X600与6x作物给100X100,然后再次调整到600X600。

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

因此,要获得更好的结果,请使用低分辨率和高分辨率时使用的处理过程与上面建议的相反。

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(); 
4

我设置图像缩放和裁切直接与:

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

它应该只适用于视频连接,但静止图像作品也像魅力。

+1

这应该是正确的答案。两行代码完美无缺地工作。谢谢Jose! – picciano