CGImage recording distortion
cgcontext, macos, nsview, objective-c, quartz-graphics
Solution
The problem with this was this line.
4*size.width,
The size.width was an odd number, not a multiple of 4. The values passed into CGBitmapContextCreate need to be a multiple of 4.
4*ceil(size.width / 4) * 4
That solved the problem.
Problem
I've written a helper class to record a NSView and save it to a QuickTime file. The view is recorded fine to a QuickTime movie but the output is skewed for some reason. The core of my class is below, and the output is this: ``` - (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; } ```