jasondinh
jasondinh

Reputation: 928

Export UIImage array to video - bluish result

I'm using AVAssetWriter with AVAssetWriterInputPixelBufferAdaptor to make a video from an array of UIImage. The result movie is playing fine, but has a blue tint all over them. I know the pixel format is not correct but don't know enough to fix the problem.

AVAssetWriterInputPixelBufferAdaptor code:

NSDictionary *sourcePixelBufferAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                                       [NSNumber numberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, nil];

AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
                                                                                                                 sourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary];

Generate CVPixelBufferRef from CGImageRef

+ (CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image
{
    CGSize frameSize = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image));
    NSDictionary *options = @{
                              (__bridge NSString *)kCVPixelBufferCGImageCompatibilityKey: @(NO),
                              (__bridge NSString *)kCVPixelBufferCGBitmapContextCompatibilityKey: @(NO)
                              };
    CVPixelBufferRef pixelBuffer;
    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, frameSize.width,
                                          frameSize.height,  kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options,
                                          &pixelBuffer);
    if (status != kCVReturnSuccess) {
        return NULL;
    }

    CVPixelBufferLockBaseAddress(pixelBuffer, 0);
    void *data = CVPixelBufferGetBaseAddress(pixelBuffer);
    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(data, frameSize.width, frameSize.height,
                                                 8, CVPixelBufferGetBytesPerRow(pixelBuffer), rgbColorSpace,
                                                 (CGBitmapInfo) kCGImageAlphaNoneSkipLast);
    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
                                           CGImageGetHeight(image)), image);
    CGColorSpaceRelease(rgbColorSpace);
    CGContextRelease(context);
    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);

    return pixelBuffer;
}

Any suggestion?

Upvotes: 1

Views: 114

Answers (1)

Gordon Childs
Gordon Childs

Reputation: 36074

When calling CGBitmapContextCreate you should pass kCGImageAlphaNoneSkipFirst and not kCGImageAlphaNoneSkipLast.

This is because your bitmaps are laid out as alpha then colour and not colour then alpha.

The reason this got you a bluish tint is because you were treating ARG as RGB. A (alpha) was zero, so your image had no red in it. Removing all red from an image will, in general, give you a bluish-green tint.

Upvotes: 2

Related Questions