2011-11-16 56 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