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; } |
Comments are closed.