2011-07-06 19 views
6

私は後で新しいプロジェクトに追加されるミニプロジェクトの作業に取り組んでいます。これは基本的にテストユニットです。画像を高速化する - iOS

AVCaptureSessionを作成し、OutputSampleBufferDelegateのメソッドを作成しています。この方法では、sampleBufferUIImageに変換し、UIImageを保存します。 iPhone 4でアプリケーションを実行すると、1秒あたり2〜3枚の画像しか保存できません。イメージを保存するには、より効率的な方法が必要です。

誰かがそれをスピードアップするのに役立つことができますか?

ありがとうございます!

lots of the code is from here

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection 
{ 
    UIImage *resultUIImage = [self imageFromSampleBuffer:sampleBuffer]; 

    NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(resultUIImage)]; 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *path = [paths objectAtIndex:0]; 

    CMTime frameTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); 

    NSString *filename = [NSString stringWithFormat:@"%f.png", CMTimeGetSeconds(frameTime)]; 

    NSString *finalPath = [path stringByAppendingString:filename]; 

    [imageData writeToFile:finalPath atomically:YES]; 
} 

// Create a UIImage from sample buffer data 
- (UIImage *)imageFromSampleBuffer:(CMSampleBufferRef)sampleBuffer 
{ 
    // Get a CMSampleBuffer's Core Video image buffer for the media data 
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    // Lock the base address of the pixel buffer 
    CVPixelBufferLockBaseAddress(imageBuffer, 0); 

    // Get the number of bytes per row for the pixel buffer 
    void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer); 

    // Get the number of bytes per row for the pixel buffer 
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
    // Get the pixel buffer width and height 
    size_t width = CVPixelBufferGetWidth(imageBuffer); 
    size_t height = CVPixelBufferGetHeight(imageBuffer); 

    // Create a device-dependent RGB color space 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    // Create a bitmap graphics context with the sample buffer data 
    CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
    // Create a Quartz image from the pixel data in the bitmap graphics context 
    CGImageRef quartzImage = CGBitmapContextCreateImage(context); 
    // Unlock the pixel buffer 
    CVPixelBufferUnlockBaseAddress(imageBuffer,0); 

    // Free up the context and color space 
    CGContextRelease(context); 
    CGColorSpaceRelease(colorSpace); 

    // Create an image object from the Quartz image 
    UIImage *image = [UIImage imageWithCGImage:quartzImage]; 

    // Release the Quartz image 
    CGImageRelease(quartzImage); 

    return image; 
} 
+0

Insturmentsでコードを表示するのに最も時間がかかるのはどのタスクですか? – Mats

答えて

8

このコードを使用して、画像を0.1秒まで保存する時間を得ることができます。

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
     fromConnection:(AVCaptureConnection *)connection 
{ 

    double frameTime = CFAbsoluteTimeGetCurrent(); 
    UIImage *resultUIImage = [self imageFromSampleBuffer:sampleBuffer]; 

    // takes freaking forever to do. 
    double pre = CFAbsoluteTimeGetCurrent(); 
    NSData *imageData = UIImageJPEGRepresentation(resultUIImage, 0.9); 
    NSLog(@"It took to write the file:%f",CFAbsoluteTimeGetCurrent()-pre); 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory 
                 ,NSUserDomainMask 
                 , YES); 
    NSString *path = [paths objectAtIndex:0]; 
    NSString *filename = [NSString stringWithFormat:@"%f.png", frameTime]; 
    NSString *finalPath = [path stringByAppendingString:filename]; 
    [imageData writeToFile:finalPath atomically:YES]; 
} 
+0

ニース。 iPhoneはイメージを内部的にJPGとして保存する必要があり、pngへの変換は実際のボトルネックであり、ディスクへの書き込みではないようです。 – Meekohi

+0

CGBitmapContextCreateImageを取得しました:無効なコンテキスト0x0。バックトレースを見たい場合は、CG_CONTEXT_SHOW_BACKTRACE環境変数を設定してください。 – loretoparisi

+0

3行目から最後の行には.jpgでないはずですか? – shim

3

あなたが最初の方法で次の行をコメントアウトした場合、あなたが生成することができますどのように多くの画像を参照してくださいでした:

[imageData writeToFile:finalPath atomically:YES]; 

私はそれはあなたが行っていると言う理由そのイメージをディスクに書き出すために多くの時間を費やしていました。画像をディスクに書き込まずにこれがどのように機能するかは興味深いでしょう。少なくとも、画像を保存するのではなく、実際に画像を作成するのにすべての時間を費やしているかどうかを知ることができます。あるいは、あなたが言及した別のポスターとして使うこともできます。

イメージをディスクに書き込むのに時間がかかりすぎる場合は、イメージをメモリにキャッシュして後でディスクに書き込むキャッシュメカニズムを実装することをお勧めします。

バックグラウンドスレッドでwriteToFile:atomically:を呼び出すと役立ちます。

+0

これにコメントしてくれてありがとう。私は一見をとり、最も長く取っていたものを測定した。それはuiimageをNSDataオブジェクトに変換していました。私はオンラインで見て、より効率的な方法を見つけた(pngの代わりにjpeg表現を使用) – SamB

関連する問題