3

CMSampleBufferRefUIImageから非圧縮画像データを取得する必要があります。私はコードを使用しています:

captureStillImageOutput captureStillImageAsynchronouslyFromConnection:connection
 completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) 
{
    // that famous function from Apple docs found on a lot of websites
    // does NOT work for still images
    UIImage *capturedImage = [self imageFromSampleBuffer:imageSampleBuffer]; 
}

http://developer.apple.com/library/ios/#qa/qa1702/_index.htmlは関数へのリンクimageFromSampleBufferです。

しかし、それは正しく機能しません。:(

方法はありますがjpegStillImageNSDataRepresentation:imageSampleBuffer、圧縮されたデータが得られます(JPEGのため)。

UIImage静止画像をキャプチャした後、最も生の非圧縮データで作成するにはどうすればよいですか?

たぶん、私はビデオ出力にいくつかの設定を指定する必要がありますか?私は現在それらを使用しています:

captureStillImageOutput = [[AVCaptureStillImageOutput alloc] init];
captureStillImageOutput.outputSettings = @{ (id)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA) };

私は、出力のデフォルト値がであることに気づきましAVVideoCodecKeyAVVideoCodecJPEG。なんらかの方法で回避できますか、それとも静止画をキャプチャするときにも問題になりますか?

そこで何かを見つけました。 「645PRO 」のようなカメラからの生の画像データですが、OpenCVやOGLES、その他のサードパーティを使用せずに、UIImageだけが必要です。

4

2 に答える 2

6

このメソッドimageFromSampleBufferは実際には機能しますが、変更されたバージョンを使用していますが、正しく覚えていれば、outputSettings を正しく設定する必要があります。kCVPixelBufferPixelFormatTypeKeyキーを として、値をとして設定する必要があると思いますkCVPixelFormatType_32BGRA

たとえば、次のようになります。

NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey;                                 
NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];                
NSDictionary* outputSettings = [NSDictionary dictionaryWithObject:value forKey:key];

[newStillImageOutput setOutputSettings:outputSettings];

編集

これらの設定を使用して、ビデオではなく静止画像を取得しています。あなたの sessionPreset AVCaptureSessionPresetPhoto はありますか? それに問題があるかもしれません

AVCaptureSession *newCaptureSession = [[AVCaptureSession alloc] init];
[newCaptureSession setSessionPreset:AVCaptureSessionPresetPhoto];

編集2

UIImage への保存に関する部分は、ドキュメントのものと同じです。それが私が問題の他の原因を求めていた理由ですが、それはストローをつかんでいただけだったと思います. 私が知っている別の方法がありますが、それには OpenCV が必要です。

- (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer{
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);

CVPixelBufferLockBaseAddress(imageBuffer, 0);

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);

}

参考にならないと思います、すいません。あなたの問題の他の原因を考えるのに十分な知識がありません。

于 2013-03-27T12:36:29.887 に答える
1

より効率的な方法は次のとおりです。

UIImage *image = [UIImage imageWithData:[self imageToBuffer:sampleBuffer]];

- (NSData *) imageToBuffer:(CMSampleBufferRef)source {
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(source);
    CVPixelBufferLockBaseAddress(imageBuffer,0);

    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
    size_t width = CVPixelBufferGetWidth(imageBuffer);
    size_t height = CVPixelBufferGetHeight(imageBuffer);
    void *src_buff = CVPixelBufferGetBaseAddress(imageBuffer);

    NSData *data = [NSData dataWithBytes:src_buff length:bytesPerRow * height];

    CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
    return data;
}
于 2016-08-20T07:47:58.723 に答える