我编写了一个帮助程序类来记录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;
}
答案 0 :(得分:3)
这就是问题所在。
4*size.width,
size.width是一个奇数,而不是4的倍数。传递给CGBitmapContextCreate的值必须是4的倍数。
4*ceil(size.width / 4) * 4
解决了这个问题。