我编写了一个帮助类来记录 NSView 并将其保存到 QuickTime 文件中。该视图可以很好地记录到 QuickTime 电影中,但由于某种原因,输出会出现偏差。我的课程的核心如下,输出是这样的:
- (void) captureImage
{
[self getCGImageFromView];
pixelBuffer = [self getPixelBufferFromCGImage:viewCGImage size:CGRectMake(0, 0, mViewRect.size.width, mViewRect.size.height).size];
if(pixelBuffer) {
if(![adapter appendPixelBuffer:pixelBuffer withPresentationTime:CMTimeMake(mCurrentFrame, 20)])
NSLog(@"AVAssetWriterInputPixelBufferAdaptor: Failed to append pixel buffer.");
CFRelease(pixelBuffer);
mCurrentFrame++;
}
}
- (void) getCGImageFromView
{
viewBitmapImageRep = [currentView bitmapImageRepForCachingDisplayInRect:mViewRect];
[currentView cacheDisplayInRect:mViewRect toBitmapImageRep:viewBitmapImageRep];
viewBitmapFormat = [viewBitmapImageRep bitmapFormat];
viewCGImage = [viewBitmapImageRep CGImage];
}
- (CVPixelBufferRef)getPixelBufferFromCGImage:(CGImageRef)image size:(CGSize)size
{
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
[NSNumber numberWithBool:YES], kCVPixelBufferOpenGLCompatibilityKey,
[NSNumber numberWithInt:size.width], kCVPixelBufferWidthKey,
[NSNumber numberWithInt:size.height], kCVPixelBufferHeightKey,
nil];
CVPixelBufferRef pxbuffer = NULL;
CVReturn status = CVPixelBufferCreate(NULL, size.width, size.height, kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options, &pxbuffer);
NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);
CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
NSParameterAssert(pxdata != NULL);
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pxdata, size.width, size.height, 8, 4*size.width, rgbColorSpace, kCGImageAlphaPremultipliedFirst);
NSParameterAssert(context);
[[currentView layer] renderInContext:context];
//CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
return pxbuffer;
}