2014-02-20 2 views
1

사진 촬영 응용 프로그램을 만들고 있습니다.CALayer에 이미지 캡처를 사용할 때 이미지 캡처가 왜곡됩니다.

[_previewLayer setFrame:CGRectMake(0, 0, rootLayer.bounds.size.width, rootLayer.bounds.size.height/2)]; 

이 완벽한 외모와 사용자가 카메라의 "미리보기"/ 그들이 무엇을보고있는를 보는 동안 왜곡이 전혀 없다 : 앱의 미리보기 층은이 코드를 사용하여 화면의 정확히 절반을 차지하도록 설정되어 사진 찍는 동안.

그러나 실제로 사진을 찍으면 하위 레이어를 만들고 프레임 속성을 내 미리보기 레이어의 속성으로 설정하고 사진을 하위 레이어의 내용으로 설정합니다.

이것은 기술적으로 효과가 있습니다. 사용자가 사진을 찍으면 화면 위쪽에 사진이 나타납니다.

유일한 문제는 사진이 왜곡된다는 것입니다.

마치 풍경 사진을 찍는 것처럼 보입니다.

어떤 도움을 주셔서 감사합니다. 저는이 일에 전적으로 필사적이며 오늘 하루 종일 작업 한 후에 문제를 해결할 수 없었습니다. 여기

는 내보기 컨트롤러의 모든 코드 :

#import "MediaCaptureVC.h" 

@interface MediaCaptureVC() 

@end 

@implementation MediaCaptureVC 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 

- (void)viewDidLoad 
{ 

    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 


    AVCaptureSession *session =[[AVCaptureSession alloc]init]; 


    [session setSessionPreset:AVCaptureSessionPresetPhoto]; 


    AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 


    NSError *error = [[NSError alloc]init]; 

    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&error]; 


    if([session canAddInput:deviceInput]) 
     [session addInput:deviceInput]; 


    _previewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:session]; 


    [_previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; 

    CALayer *rootLayer = [[self view]layer]; 

    [rootLayer setMasksToBounds:YES]; 


    [_previewLayer setFrame:CGRectMake(0, 0, rootLayer.bounds.size.width, rootLayer.bounds.size.height/2)]; 


    [rootLayer insertSublayer:_previewLayer atIndex:0]; 


    _stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; 

    [session addOutput:_stillImageOutput]; 

    [session startRunning]; 


    } 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 


-(UIImage*) rotate:(UIImage*) src andOrientation:(UIImageOrientation)orientation 
{ 
    UIGraphicsBeginImageContext(src.size); 

    CGContextRef context=(UIGraphicsGetCurrentContext()); 

    if (orientation == UIImageOrientationRight) { 
     CGContextRotateCTM (context, 90/180*M_PI) ; 
    } else if (orientation == UIImageOrientationLeft) { 
     CGContextRotateCTM (context, -90/180*M_PI); 
    } else if (orientation == UIImageOrientationDown) { 
     // NOTHING 
    } else if (orientation == UIImageOrientationUp) { 
     CGContextRotateCTM (context, 90/180*M_PI); 
    } 

    [src drawAtPoint:CGPointMake(0, 0)]; 
    UIImage *img=UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return img; 

} 



-(IBAction)stillImageCapture { 

    AVCaptureConnection *videoConnection = nil; 
    for (AVCaptureConnection *connection in _stillImageOutput.connections){ 
     for (AVCaptureInputPort *port in [connection inputPorts]){ 

      if ([[port mediaType] isEqual:AVMediaTypeVideo]){ 

       videoConnection = connection; 
       break; 
      } 
     } 
     if (videoConnection) { 
      break; 
     } 
    } 

    NSLog(@"about to request a capture from: %@", _stillImageOutput); 

[_stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) { 


if(imageDataSampleBuffer) { 

      NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; 


      UIImage *image = [[UIImage alloc]initWithData:imageData]; 


     image = [self rotate:image andOrientation:image.imageOrientation]; 


      CALayer *subLayer = [CALayer layer]; 

      CGImageRef imageRef = image.CGImage; 

    subLayer.contents = (id)[UIImage imageWithCGImage:imageRef].CGImage; 

      subLayer.frame = _previewLayer.frame; 

      CALayer *rootLayer = [[self view]layer]; 

      [rootLayer setMasksToBounds:YES]; 

      [subLayer setFrame:CGRectMake(0, 0, rootLayer.bounds.size.width, rootLayer.bounds.size.height/2)]; 

      [_previewLayer addSublayer:subLayer]; 


      NSLog(@"%@", subLayer.contents); 

      NSLog(@"Orientation: %d", image.imageOrientation); 

     } 

    }]; 

} 

@end 
+0

이미지 뷰의 콘텐츠 모드를 설정할 수 있습니다. – Manthan

답변

0

안녕이 당신을 도움이되기를 바랍니다 -

코드는 코드의 대부분의 CALayer에서 수행되기 때문에 그것이 있어야하는 것보다 더 복잡한 것 같다 레벨 대신에 imageView/view 레벨을 사용하지만,이 문제는 원래 캡처에서부터 미니 뷰포트까지 프레임의 비율이 다르다는 것과이 구문에서 UIImage가 왜곡되고 있다는 것입니다.

sublayer.frame의 비율을 캡처하여 루트 레이어 또는 이와 관련된 이미지보기에 적합한 최적의 크기를 얻으십시오.

다음과 같은 코드가 있습니다. 서브 루틴 코드 그 비율을 처리하기 전에 (당신은 당신이 원하는 것을 얻을 수있는 프레임의 원점을 조정해야합니다주의!)

... CGRect newbounds = [자기 figure_proportion : 이미지 to_fit_rect (rootLayer.frame) (newbounds 경우 .size.height < rootLayer.frame.size.height) { rootLayer ..... (이미지 뷰 프레임의 원점 조정 코드)

-(CGRect) figure_proportion:(UIImage *) image2 to_fit_rect:(CGRect) rect { 
    CGSize image_size = image2.size; 
     CGRect newrect = rect; 
    float wfactor = image_size.width/ image_size.height; 
    float hfactor = image_size.height/ image_size.width; 

    if (image2.size.width > image2.size.height) { 
     newrect.size.width = rect.size.width; 
     newrect.size.height = (rect.size.width * hfactor); 
    } 
    else if (image2.size.height > image2.size.width) { 
     newrect.size.height = rect.size.height; 
     newrect.size.width = (rect.size.height * wfactor); 
    } 
    else { 
     newrect.size.width = rect.size.width; 
     newrect.size.height = newrect.size.width; 
    } 
    if (newrect.size.height > rect.size.height) { 
     newrect.size.height = rect.size.height; 
     newrect.size.width = (newrect.size.height* wfactor); 
    } 
    if (newrect.size.width > rect.size.width) { 
     newrect.size.width = rect.size.width; 
     newrect.size.height = (newrect.size.width* hfactor); 
    } 
    return(newrect); 


    }