iphone - 将 UIImage 转换为 CMSampleBufferRef

标签 iphone ios objective-c video avfoundation

我正在使用 AVFoundation 进行视频录制。我必须将视频裁剪为 320x280。我正在获取 CMSampleBufferRef 并使用以下代码将其转换为 UIImage。

CGImageRef _cgImage = [self imageFromSampleBuffer:sampleBuffer];
UIImage *_uiImage = [UIImage imageWithCGImage:_cgImage];
CGImageRelease(_cgImage);
_uiImage = [_uiImage resizedImageWithSize:CGSizeMake(320, 280)];

CMSampleBufferRef croppedBuffer = /* NEED HELP WITH THIS */

[_videoInput appendSampleBuffer:sampleBuffer]; 
// _videoInput is a AVAssetWriterInput

imageFromSampleBuffer: 方法如下所示:

- (CGImageRef) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer // Create a CGImageRef from sample buffer data
{
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(imageBuffer,0);        // Lock the image buffer

    uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0);   // Get information of the image
    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);
    CVPixelBufferUnlockBaseAddress(imageBuffer,0);
    /* CVBufferRelease(imageBuffer); */  // do not call this!

    return newImage;
}

现在我必须将调整大小的图像转换回 CMSampleBufferRef 以写入 AVAssetWriterInput

如何将 UIImage 转换为 CMSampleBufferRef

谢谢大家!

最佳答案

虽然您可以从头开始创建自己的 Core Media 样本缓冲区,但使用 AVPixelBufferAdaptor 可能更容易.

您在 inputSettings 字典中描述源像素缓冲区格式并将其传递给适配器初始化程序:

NSMutableDictionary* inputSettingsDict = [NSMutableDictionary dictionary];
[inputSettingsDict setObject:[NSNumber numberWithInt:pixelFormat] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey];
[inputSettingsDict setObject:[NSNumber numberWithUnsignedInteger:(NSUInteger)(image.uncompressedSize/image.rect.size.height)] forKey:(NSString*)kCVPixelBufferBytesPerRowAlignmentKey];
[inputSettingsDict setObject:[NSNumber numberWithDouble:image.rect.size.width] forKey:(NSString*)kCVPixelBufferWidthKey];
[inputSettingsDict setObject:[NSNumber numberWithDouble:image.rect.size.height] forKey:(NSString*)kCVPixelBufferHeightKey];
[inputSettingsDict setObject:[NSNumber numberWithBool:YES] forKey:(NSString*)kCVPixelBufferCGImageCompatibilityKey];
[inputSettingsDict setObject:[NSNumber numberWithBool:YES] forKey:(NSString*)kCVPixelBufferCGBitmapContextCompatibilityKey];
AVAssetWriterInputPixelBufferAdaptor* pixelBufferAdapter = [[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:assetWriterInput sourcePixelBufferAttributes:inputSettingsDict];

然后您可以将 CVPixelBuffers 附加到您的适配器:

[pixelBufferAdapter appendPixelBuffer:completePixelBuffer withPresentationTime:pixelBufferTime]

pixelbufferAdaptor 接受 CVPixelBuffers,因此您必须将 UIImages 转换为 pixelBuffers,这在此处描述:https://stackoverflow.com/a/3742212/100848
UIImageCGImage 属性传递给 newPixelBufferFromCGImage

关于iphone - 将 UIImage 转换为 CMSampleBufferRef,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16475737/

相关文章:

ios - 如何通过ios客户端获取 Stripe 卡详细信息

iphone - 可以在 iPhone 上使用 NSUserDefaults 保存整数数组吗?

javascript - iPhone Safari 中的详细错误报告?

ios - UICKeyChainStore 不保存数据

ios - 当用户将设备从纵向模式旋转到横向模式时,如何使UIView全屏显示

javascript - 当 DOM 在 iOS 中准备就绪时,如何强制关注文本字段?

iphone - 摄氏度符号问题 - Objective-C

ios - 在启用 Assets 库的 Xcode 5 中修改 Info.plist 的 CFBundleVersion

ios - 如何通过 objective-c 中的 POST 请求捕获 stderr 输出并将消息发送到远程日志文件?

ios - libsqlite3.dylib 框架意外从 xcode 中删除