priore

Create movie from array of images

May 21st, 2012
875
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. - (void) writeImagesAsMovie:(NSArray *)array toPath:(NSString*)path {
  2.    
  3. NSString *documents = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex: 0];
  4.     documents = [documents stringByAppendingPathComponent:currentWorkspace];
  5.    
  6.     //NSLog(path);
  7.     NSString *filename = [documents stringByAppendingPathComponent:[array objectAtIndex:0]];
  8.     UIImage *first = [UIImage imageWithContentsOfFile:filename];
  9.    
  10.    
  11.     CGSize frameSize = first.size;
  12.    
  13.     NSError *error = nil;
  14.     AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:
  15.                                   [NSURL fileURLWithPath:path] fileType:AVFileTypeQuickTimeMovie
  16.                                                               error:&error];
  17.    
  18.     if(error) {
  19.         NSLog(@"error creating AssetWriter: %@",[error description]);
  20.     }
  21.     NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
  22.                                    AVVideoCodecH264, AVVideoCodecKey,
  23.                                    [NSNumber numberWithInt:frameSize.width], AVVideoWidthKey,
  24.                                    [NSNumber numberWithInt:frameSize.height], AVVideoHeightKey,
  25.                                    nil];
  26.    
  27.    
  28.    
  29.     AVAssetWriterInput* writerInput = [[AVAssetWriterInput
  30.                                         assetWriterInputWithMediaType:AVMediaTypeVideo
  31.                                         outputSettings:videoSettings] retain];
  32.    
  33.     NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
  34.     [attributes setObject:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey];
  35.     [attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.width] forKey:(NSString*)kCVPixelBufferWidthKey];
  36.     [attributes setObject:[NSNumber numberWithUnsignedInt:frameSize.height] forKey:(NSString*)kCVPixelBufferHeightKey];
  37.    
  38.     AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
  39.                                                      assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
  40.                                                      sourcePixelBufferAttributes:attributes];
  41.    
  42.     [videoWriter addInput:writerInput];
  43.    
  44.     // fixes all errors
  45.     writerInput.expectsMediaDataInRealTime = YES;
  46.    
  47.     //Start a session:
  48.     BOOL start = [videoWriter startWriting];
  49.     NSLog(@"Session started? %d", start);
  50.     [videoWriter startSessionAtSourceTime:kCMTimeZero];
  51.  
  52.  CVPixelBufferRef buffer = NULL;
  53.     buffer = [self pixelBufferFromCGImage:[first CGImage]];
  54.     BOOL result = [adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero];
  55.    
  56.     if (result == NO) //failes on 3GS, but works on iphone 4
  57.         NSLog(@"failed to append buffer");
  58.    
  59.     if(buffer)
  60.         CVBufferRelease(buffer);
  61.    
  62.     [NSThread sleepForTimeInterval:0.05];
  63.  
  64.    
  65.     int reverseSort = NO;
  66.     NSArray *newArray = [array sortedArrayUsingFunction:sort context:&reverseSort];
  67.    
  68.     delta = 1.0/[newArray count];
  69.    
  70.     int fps = (int)fpsSlider.value;
  71.    
  72.     int i = 0;
  73.     for (NSString *filename in newArray)
  74.     {
  75.         if (adaptor.assetWriterInput.readyForMoreMediaData)
  76.         {
  77.            
  78.             i++;
  79.             NSLog(@"inside for loop %d %@ ",i, filename);
  80.             CMTime frameTime = CMTimeMake(1, fps);
  81.             CMTime lastTime=CMTimeMake(i, fps);
  82.             CMTime presentTime=CMTimeAdd(lastTime, frameTime);
  83.            
  84.             NSString *filePath = [documents stringByAppendingPathComponent:filename];
  85.            
  86.             UIImage *imgFrame = [UIImage imageWithContentsOfFile:filePath] ;
  87.             buffer = [self pixelBufferFromCGImage:[imgFrame CGImage]];
  88.             BOOL result = [adaptor appendPixelBuffer:buffer withPresentationTime:presentTime];
  89.            
  90.             if (result == NO) //failes on 3GS, but works on iphone 4
  91.             {
  92.                 NSLog(@"failed to append buffer");
  93.                 NSLog(@"The error is %@", [videoWriter error]);
  94.             }
  95.             if(buffer)
  96.                 CVBufferRelease(buffer);
  97.             [NSThread sleepForTimeInterval:0.05];
  98.         }
  99.         else
  100.         {
  101.             NSLog(@"error");
  102.             i--;
  103.         }
  104.         [NSThread sleepForTimeInterval:0.02];
  105.     }
  106.    
  107.     //Finish the session:
  108.     [writerInput markAsFinished];
  109.     [videoWriter finishWriting];
  110.     CVPixelBufferPoolRelease(adaptor.pixelBufferPool);
  111.     [videoWriter release];
  112.     [writerInput release];
  113. }
  114.  
  115. - (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image
  116. {
  117.     NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
  118.                              [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey,
  119.                              [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
  120.                              nil];
  121.     CVPixelBufferRef pxbuffer = NULL;
  122.    
  123.     CVPixelBufferCreate(kCFAllocatorDefault, CGImageGetWidth(image),
  124.                         CGImageGetHeight(image), kCVPixelFormatType_32ARGB, (CFDictionaryRef) options,
  125.                         &pxbuffer);
  126.    
  127.     CVPixelBufferLockBaseAddress(pxbuffer, 0);
  128.     void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
  129.    
  130.     CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
  131.     CGContextRef context = CGBitmapContextCreate(pxdata, CGImageGetWidth(image),
  132.                                                  CGImageGetHeight(image), 8, 4*CGImageGetWidth(image), rgbColorSpace,
  133.                                                  kCGImageAlphaNoneSkipFirst);
  134.    
  135.     CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
  136.    
  137.     CGAffineTransform flipVertical = CGAffineTransformMake(
  138.                                                            1, 0, 0, -1, 0, CGImageGetHeight(image)
  139.                                                            );
  140.     CGContextConcatCTM(context, flipVertical);
  141.    
  142.    
  143.    
  144.     CGAffineTransform flipHorizontal = CGAffineTransformMake(
  145.                                                              -1.0, 0.0, 0.0, 1.0, CGImageGetWidth(image), 0.0
  146.                                                              );
  147.    
  148.     CGContextConcatCTM(context, flipHorizontal);
  149.    
  150.    
  151.     CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
  152.                                            CGImageGetHeight(image)), image);
  153.     CGColorSpaceRelease(rgbColorSpace);
  154.     CGContextRelease(context);
  155.    
  156.     CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
  157.    
  158.     return pxbuffer;
  159. }
Add Comment
Please, Sign In to add comment