3

我编写了一个帮助类来记录 NSView 并将其保存到 QuickTime 文件中。该视图可以很好地记录到 QuickTime 电影中,但由于某种原因,输出会出现偏差。我的课程的核心如下,输出是这样的:

倾斜的 .mov 文件

- (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;
}
4

1 回答 1

5

这个问题是这条线。

 4*size.width, 

size.width 是奇数,不是 4 的倍数。传递给 CGBitmapContextCreate 的值必须是 4 的倍数。

4*ceil(size.width / 4) * 4

这解决了问题。

于 2013-02-28T11:58:35.363 回答