mdominick
mdominick

Reputation: 1319

Export UIImages to MP4

Ok so I am in a bind and I have been staring at this for too long to think clearly.

Basically, all I need is a method that takes in an NSArray of images and writes an mp4 or other video format to disk.

I am not worried about monitoring the user's gesture or anything like that. The images already exist on disk -- I just need to do the conversion.

I understand that I need an AVWriter and something like:

- (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image
{
  NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                         [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
                         [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                         nil];
  CVPixelBufferRef pxbuffer = NULL;

  CVPixelBufferCreate(kCFAllocatorDefault, CGImageGetWidth(image),
                    CGImageGetHeight(image), kCVPixelFormatType_32ARGB, (CFDictionaryRef) options,
                    &pxbuffer);

  CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);

  CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
  CGContextRef context = CGBitmapContextCreate(pxdata, CGImageGetWidth(image),
                                             CGImageGetHeight(image), 8, 4*CGImageGetWidth(image), rgbColorSpace,
                                             kCGImageAlphaNoneSkipFirst);

  CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));

//    CGAffineTransform flipVertical = CGAffineTransformMake(
//                                                           1, 0, 0, -1, 0, CGImageGetHeight(image)
//                                                           );
//    CGContextConcatCTM(context, flipVertical);



//    CGAffineTransform flipHorizontal = CGAffineTransformMake(
//                                                             -1.0, 0.0, 0.0, 1.0, CGImageGetWidth(image), 0.0
//                                                             );
//
//    CGContextConcatCTM(context, flipHorizontal);


  CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
                                       CGImageGetHeight(image)), image);
  CGColorSpaceRelease(rgbColorSpace);
  CGContextRelease(context);

  CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

  return pxbuffer;
}

I just can't see how to put it all into one clean helper. And before you ask I have seen: How to display video from images and the like, but just running the images in a UIImageView is not what I am looking for here. This needs to be App Store legal, so FFMPeg is not an option.

Any thoughts / guidance?

Upvotes: 4

Views: 1899

Answers (1)

Jano
Jano

Reputation: 63667

https://github.com/meslater/MSImageMovieEncoder encodes images to H.264. You have to provide images as context refs or CVPixelBufferRefs (see sample code here) implementing

-(BOOL)nextFrameInCVPixelBuffer:(CVPixelBufferRef*)pixelBuf;

Each call to this method should return a buffer and YES. If there are no more images return NO, and you'll find the movie on disk.

For more details, read How do I export UIImage array as a movie? (it's basically the same code) or read the github files.

Upvotes: 1

Related Questions