1

だから私は、ユーザーが画像やビデオをキャプチャしてフィルターを適用できるようにするビデオ キャプチャ プロジェクトに取り組んできました。私は AVfoundation フレームワークを使用しています。静止画像をキャプチャし、ビデオ フレームを UIImage オブジェクトとしてキャプチャすることに成功しました。残っているのは、ビデオを録画することだけです。

ここに私のコードがあります:

- (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 を変更可能な配列にストックしようとしましたが、それはばかげた考えでした。何かご意見は?どんな助けでも大歓迎です

4

1 に答える 1

1

CIFilter を使用していますか? そうでない場合は、高速な GPU ベースの変換を検討する必要があります。

生成後、対応する画像を A​​VAssetWriter に直接記録したい場合があります。Apple が提供する RosyWriter のサンプル コードを参照してください。要約すると、彼らは AVAssetWriter を使用してフレームを一時ファイルにキャプチャし、終了したらそのファイルをカメラに保存します。

ただし、1 つの警告は、私の第 4 世代 iPod touch で RosyWriter が 4fps を取得していたことです。彼らは、CPU 上のピクセルを力ずくで変更しています。Core Image は GPU ベースのフィルターを実行し、12 fps を達成できましたが、これは私の意見では、まだあるべきものではありません。

幸運を!

于 2012-07-17T15:25:36.367 に答える