UIImage 数组转为视频

主要功能是将一个UIImage数组转为视频,并且存入相册。直接给出.m文件吧:

//
//  PViewController.m
//  test
//
//  Created by pingshw on 14-3-30.
//  Copyright (c) 2014年 pingshw. All rights reserved.
//

#import "PViewController.h"
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
#define kCGImageAlphaPremultipliedLast  (kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast)
#else
#define kCGImageAlphaPremultipliedLast  kCGImageAlphaPremultipliedLast
#endif

#define DOCSFOLDER [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/"]
#define VideoPath [DOCSFOLDER stringByAppendingPathComponent:@"test.mov"] //注意格式!
#define w 320
#define h 480
@interface PViewController ()
{
    NSMutableArray *imageArr;
    NSDictionary *options;
}
@end

@implementation PViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    [self startRecord:VideoPath];
}

-(CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image size:(CGSize)size
{
    CVPixelBufferRef pxbuffer = NULL;
    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, w, h, kCVPixelFormatType_32ARGB, (CFDictionaryRef) CFBridgingRetain(options), &pxbuffer);
    
    NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);
    
    CVPixelBufferLockBaseAddress(pxbuffer, 0);
    void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
    NSParameterAssert(pxdata != NULL);
    
    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pxdata, size.width, size.height, 8, 4*size.width, rgbColorSpace, kCGImageAlphaPremultipliedLast);
    NSParameterAssert(context);
    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
    CGColorSpaceRelease(rgbColorSpace);
    CGContextRelease(context);
    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);
    return pxbuffer;
}

-(void)startRecord:(NSString *)moviePath
{
    NSDate *start = [NSDate date];
    
    if([[NSFileManager defaultManager] fileExistsAtPath:moviePath])
    {
        [[NSFileManager defaultManager] removeItemAtPath:moviePath error:nil];
    }
    
    imageArr = [[NSMutableArray alloc] init];
    float total = 30.0;
    int i = total;
    while (i >0) {
        i--;
        UIGraphicsBeginImageContext(CGSizeMake(w, h));
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetRGBFillColor(context, i/total, i/total, i/total, 1);
        CGContextFillRect(context, CGRectMake(0, 0, w, h));
        UIImage *image= UIGraphicsGetImageFromCurrentImageContext();
        [imageArr addObject:image];
        UIGraphicsEndImageContext();
        NSLog(@"%d",i);
    }//这里是生成了一个长度为total的测试数组,图片是纯色,颜色渐变,实际使用时替换为实际UIImage数组即可。
    
    CGSize size = CGSizeMake(w, h);
    NSError *error = nil;
    
    unlink([moviePath UTF8String]);
    AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:moviePath]
                                                           fileType:AVFileTypeQuickTimeMovie
                                                              error:&error];
    NSParameterAssert(videoWriter);
    if(error)
        NSLog(@"error = %@", [error localizedDescription]);
    
    NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecH264, AVVideoCodecKey,
                                   [NSNumber numberWithInt:size.width], AVVideoWidthKey,
                                   [NSNumber numberWithInt:size.height], AVVideoHeightKey, nil];
    AVAssetWriterInput *writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
    NSDictionary *sourcePixelBufferAttributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, nil];
    
    AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
                                                     assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput sourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary];
    NSParameterAssert(writerInput);
    NSParameterAssert([videoWriter canAddInput:writerInput]);
    
    if ([videoWriter canAddInput:writerInput])
        NSLog(@"start");
    
    [videoWriter addInput:writerInput];
    
    [videoWriter startWriting];
    [videoWriter startSessionAtSourceTime:kCMTimeZero];
    
    dispatch_queue_t dispatchQueue = dispatch_queue_create("record", NULL);
    int __block frame = 0;
    
    [writerInput requestMediaDataWhenReadyOnQueue:dispatchQueue usingBlock:^{
        
        CVPixelBufferRef buffer = NULL;
        while ([writerInput isReadyForMoreMediaData])
        {
            if([imageArr count] == 0)
            {
                [writerInput markAsFinished];
                [videoWriter finishWritingWithCompletionHandler:^{
                    UISaveVideoAtPathToSavedPhotosAlbum (moviePath,nil,nil, nil);
                }];//存入相册,模拟器调试在模拟器文件夹能看到视频,真机调试在相册能找到存入的视频。
                
                if (buffer)
                {
                    CFRelease(buffer);
                    buffer = NULL;
                }
                
                break;
            }
            else
            {
                if (buffer==NULL)
                {
                    buffer = [self pixelBufferFromCGImage:[[imageArr objectAtIndex:0] CGImage] size:size];
                }
                
                if (buffer)
                {
                    CFAbsoluteTime interval = (total - [imageArr count]) * 50.0;//帧与帧的时间间隔
                    CMTime currentSampleTime = CMTimeMake((int)interval, 1000);
                    
                    if([adaptor appendPixelBuffer:buffer withPresentationTime:currentSampleTime])
                    {
                        ++frame;
                        [imageArr removeObjectAtIndex:0];
                        CFRelease(buffer);
                        buffer = NULL;
                    }
                }
                
            }
        }
    }];
    
    NSDate *end = [NSDate date];
    NSLog(@"%f",[end timeIntervalSinceDate:start]);//测试了下,真机,这个程序要跑0.55s
}


@end


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值