2012-07-03 3 views
1

그래서 나는 사용자가 이미지와 비디오를 캡처하고 필터를 적용 할 수있는 비디오 캡처 프로젝트를 진행 해왔다. 저는 AVfoundation 프레임 워크를 사용하여 스틸 이미지를 캡처하고 UIImage Objects로 비디오 프레임을 캡처하는 데 성공했습니다. 남은 유일한 것은 비디오를 녹화하는 것입니다.스타킹 UIImages 다음 동영상으로 변환

- (void)initCapture { 

    AVCaptureSession *session = [[AVCaptureSession alloc] init]; 
    session.sessionPreset = AVCaptureSessionPresetMedium; 



    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 

    NSError *error = nil; 
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; 
    if (!input) { 
     // Handle the error appropriately. 
     NSLog(@"ERROR: trying to open camera: %@", error); 
    } 
    [session addInput:input]; 




    stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; 
    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil]; 
    [stillImageOutput setOutputSettings:outputSettings]; 
    [session addOutput:stillImageOutput]; 


    captureOutput = [[AVCaptureVideoDataOutput alloc] init]; 
    captureOutput.alwaysDiscardsLateVideoFrames = YES; 


    dispatch_queue_t queue; 
    queue = dispatch_queue_create("cameraQueue", NULL); 
    [captureOutput setSampleBufferDelegate:self queue:queue]; 
    dispatch_release(queue); 

    NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey; 

    NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; 

    NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key]; 
    [captureOutput setVideoSettings:videoSettings];  

    [session addOutput:captureOutput]; 

    [session startRunning];  
} 




- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
     fromConnection:(AVCaptureConnection *)connection 
{ 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 

    CVPixelBufferLockBaseAddress(imageBuffer,0); 
    uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer); 
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
    size_t width = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer); 
     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
    CGImageRef newImage = CGBitmapContextCreateImage(newContext); 


    CGContextRelease(newContext); 
    CGColorSpaceRelease(colorSpace); 


    UIImage *image= [UIImage imageWithCGImage:newImage scale:1.0 orientation:UIImageOrientationRight]; 

    CGImageRelease(newImage); 

    UIImage *ima = [filter applyFilter:image]; 

    /*if(isRecording == YES) 
    { 
     [imageArray addObject:ima]; 
    } 
    NSLog(@"Count= %d",imageArray.count);*/ 

    [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:ima waitUntilDone:YES]; 


    CVPixelBufferUnlockBaseAddress(imageBuffer,0); 

    [pool drain]; 

} 

내가 변경 가능한 배열의 UIImages 스타킹 시도하지만 그건 바보 같은 생각이었다

여기 내 코드입니다. 의견이 있으십니까? 도움이 되겠습니다.

답변

1

CIFilter를 사용하고 계십니까? 그렇지 않다면, 아마 당신은 GPU 기반의 신속한 변환을 원할 것입니다.

생성 한 후 해당 이미지를 AVAssetWriter에 직접 기록하고자 할 수 있습니다. Apple에서 제공하는 RosyWriter 샘플 코드를 살펴보십시오. 요약하면 AVAssetWriter를 사용하여 프레임을 임시 파일로 캡처 한 다음 끝나면 해당 파일을 카메라에 저장합니다.

그러나 한 가지 경고는 RosyWriter가 제 4 세대 iPod touch에서 4fps를 얻고 있다는 것입니다. 그들은 CPU의 픽셀을 무차별 변경하고 있습니다. Core Image는 GPU 기반의 필터를 사용하며 12fps를 달성 할 수있었습니다. 내 의견으로는 여전히 그래야만하는 것이 아닙니다.

행운을 빈다.

관련 문제