2011-11-16 3 views
9

Je travaille avec la fonctionnalité de zoom dans la caméra AVFoundation, j'ai mis en œuvre le zoom en mettant à l'échelle la vue qui a AVCaptureVideoPreviewLayer. Maintenant, je veux capturer l'image agrandie.Capture d'une vue d'aperçu agrandie dans AVFoundation

ici est mon code pour ajouter AVFoundationVideoPreviewLayer à la vue:

// 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]]; 

code pour zoomer vue aperçu

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

Maintenant, je veux saisir cette image zoomée de previewView

Merci à l'avance .

Répondre

7

Enfin, j'ai réussi à ajouter une photo zoomée de capture dans mon application. C'est un peu moche mais ça marche. J'ai utilisé le code UIImage + redimensionner à partir du réseau, puis mis à l'échelle l'image à l'échelle de zoom, et la position de décalage calculée pour la région agrandie [qui est visible dans la vue caméra] puis je recadrée.

Maintenant, mon application se bloque parfois lorsque l'échelle de zoom est au maximum, c'est-à-dire à 6x. Je reçois un problème de mémoire car l'image agrandie est trop grande, je vais poser cette question comme une autre question.

En espérant que ce code pourrait être utile pour quelqu'un.

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

d'autres meilleures solutions? – kadungon

+1

En ce qui concerne votre accident: Commencez simplement par recadrer que redimensionner pour résoudre votre problème de mémoire. Ne calculez pas une grande image si vous en laissez tomber la majeure partie plus tard. – CipherCom

+0

J'ai essayé votre code mais je ne pouvais pas comprendre cameraZoom et le résultat final est toujours une image vide. Pouvez-vous partager plus? –

2

Vous devriez essayer d'abord recadrer puis redimensionner, de cette façon vous ne rencontrerez pas de problème de mémoire. Ce que vous faites maintenant est comme: L'image 600X600 deviendra 3600X3600 quand 6x, alors vous recadrez, cela donnera 600X600 de nouveau. Mais, pourquoi ne pas essayer 600X600 avec recadrage de 6x donne 100X100, puis redimensionner à 600X600 à nouveau. Il est possible que si la résolution d'origine est faible, l'image de sortie des deux processus diffère un peu, mais si la résolution d'origine est 8MP/5MP/3MP (la plus élevée en 5/4s/4/3G), la sortie sera similaire . Donc, pour obtenir de meilleurs résultats, utilisez votre processus lorsque vous utilisez une résolution faible et pour une résolution haute, inversez celui que j'ai suggéré ci-dessus.

0

J'ai été capable d'effectuer un recadrage en premier, puis de zoomer en utilisant des transformations d'image graphique de base. Notez que nous conservons la taille et l'échelle de l'image d'origine dans le tampon d'image et effectuons la fonction de zoom complètement avec les opérations de transformation sur les pixels individuels. Notez que ce code ne prend pas en compte l'orientation de l'appareil (dans mon cas, je ne l'utilise portrait verticale actuellement), mais pourrait facilement être accompli avec une rotation supplémentaire transform:

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

J'installe échelle de l'image et la culture directement avec:

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

Il censé fonctionner uniquement avec des connexions vidéo, mais pour l'image fonctionne toujours aussi comme un charme.

+1

Cela devrait être la bonne réponse.Deux lignes de code et fonctionne parfaitement. Merci Jose! – picciano