Create movie from array of images
Categories: iOS, iPad, iPhone on Jan.30, 2012
Create movie from images seq.
First part of method, initialize
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | - (void) writeImagesAsMovie:(NSArray *)array toPath:(NSString*)path { NSString *documents = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex: 0]; documents = [documents stringByAppendingPathComponent:currentWorkspace]; //NSLog(path); NSString *filename = [documents stringByAppendingPathComponent:[array objectAtIndex:0]]; UIImage *first = [UIImage imageWithContentsOfFile:filename]; CGSize frameSize = first.size; NSError *error = nil; AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL: [NSURL fileURLWithPath:path] fileType:AVFileTypeQuickTimeMovie error:&error]; if(error) { NSLog(@"error creating AssetWriter: %@",[error description]); } NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys: AVVideoCodecH264, AVVideoCodecKey, [NSNumber numberWithInt:frameSize.width], AVVideoWidthKey, [NSNumber numberWithInt:frameSize.height], AVVideoHeightKey, nil]; AVAssetWriterInput* writerInput = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings] retain]; NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init]; [attributes setObject:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey]; [attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.width] forKey:(NSString*)kCVPixelBufferWidthKey]; [attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.height] forKey:(NSString*)kCVPixelBufferHeightKey]; AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput sourcePixelBufferAttributes:attributes]; [videoWriter addInput:writerInput]; // fixes all errors writerInput.expectsMediaDataInRealTime = YES; //Start a session: BOOL start = [videoWriter startWriting]; NSLog(@"Session started? %d", start); [videoWriter startSessionAtSourceTime:kCMTimeZero]; |
Second part, writing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | CVPixelBufferRef buffer = NULL; buffer = [self pixelBufferFromCGImage:[first CGImage]]; BOOL result = [adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero]; if (result == NO) //failes on 3GS, but works on iphone 4 NSLog(@"failed to append buffer"); if(buffer) CVBufferRelease(buffer); [NSThread sleepForTimeInterval:0.05]; int reverseSort = NO; NSArray *newArray = [array sortedArrayUsingFunction:sort context:&reverseSort]; delta = 1.0/[newArray count]; int fps = (int)fpsSlider.value; int i = 0; for (NSString *filename in newArray) { if (adaptor.assetWriterInput.readyForMoreMediaData) { i++; NSLog(@"inside for loop %d %@ ",i, filename); CMTime frameTime = CMTimeMake(1, fps); CMTime lastTime=CMTimeMake(i, fps); CMTime presentTime=CMTimeAdd(lastTime, frameTime); NSString *filePath = [documents stringByAppendingPathComponent:filename]; UIImage *imgFrame = [UIImage imageWithContentsOfFile:filePath] ; buffer = [self pixelBufferFromCGImage:[imgFrame CGImage]]; BOOL result = [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime]; if (result == NO) //failes on 3GS, but works on iphone 4 { NSLog(@"failed to append buffer"); NSLog(@"The error is %@", [videoWriter error]); } if(buffer) CVBufferRelease(buffer); [NSThread sleepForTimeInterval:0.05]; } else { NSLog(@"error"); i--; } [NSThread sleepForTimeInterval:0.02]; } //Finish the session: [writerInput markAsFinished]; [videoWriter finishWriting]; CVPixelBufferPoolRelease(adaptor.pixelBufferPool); [videoWriter release]; [writerInput release]; } |
Convert UIImage to CVPixelBufferRef
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | - (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; } |
Similar posts:

March 17th, 2012 on 11:35 am
Hi, could you send me this article’s source code for study? I tried as it says, but my program dosn’t work, I do not know why. 3x a lot!
September 6th, 2012 on 6:33 pm
Hey I try code. But its crash for me Can you mail me this code for self study please?
September 6th, 2012 on 11:00 pm
@akii you can get it here https://github.com/sakrist/One-minute
September 7th, 2012 on 5:05 am
I don`t know what fpsSlider for, I try this code but it generate an error when compiling – undeclared variable
Thanks.
September 7th, 2012 on 11:39 am
@feeliwood
fpsSlider – it’s images per second
you can try https://github.com/sakrist/One-minute, that project based on this code
September 12th, 2012 on 9:54 am
hi, I did download your project and I made use of the two above functions well but there`s a problem.
I split a video to an array of images and use the above functions to reassemble them to the video again but the newly created video is up-side-down compared to the original one.
I was looking for the solution and I was also confused by two many things : AVAssetWriter, AVAssetWriterInput, AVAssetWriterInputPixelBufferAdaptor… I still don`t understand the relationship between these objects yet.
Thanks
February 15th, 2013 on 10:37 pm
Hi,
I have download this code and it’s really help me but i have problem with one place. Same as you have did I have list of images which is taken from iphone camera. now when i resize that image and try to create the video with that size the video is created but not proper images are totaly perfect but the video is not proper.
Can you tell me how can i resize thet video size without effecting the video qulity,