IOS多张图片合成一个视频
来源:互联网 发布:java雷电游戏源代码 编辑:程序博客网 时间:2024/05/02 02:45
图片合成视频
首先需要导入的三个依赖库
AVKit.framework MediaPlayer.framework AVFoundation.framework
下面代码中的注释很清楚, 就不做多解释, 直接上代码了
#import "ViewController.h"#import <AVFoundation/AVFoundation.h>#import <MediaPlayer/MediaPlayer.h>#import <AVKit/AVKit.h>@interface ViewController (){ NSMutableArray *imageArr;//未压缩的图片 NSMutableArray *imageArray;//经过压缩的图片}@property (nonatomic, strong) NSString *theVideoPath;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; imageArray = [[NSMutableArray alloc] init]; imageArr =[[NSMutableArray alloc]initWithObjects: [UIImage imageNamed:@"IMG_3811.jpg"],[UIImage imageNamed:@"IMG_3812.jpg"],[UIImage imageNamed:@"IMG_3813.jpg"],[UIImage imageNamed:@"IMG_3814.jpg"],[UIImage imageNamed:@"IMG_3815.jpg"],[UIImage imageNamed:@"IMG_3816.jpg"],[UIImage imageNamed:@"IMG_3817.jpg"],[UIImage imageNamed:@"IMG_3818.jpg"],[UIImage imageNamed:@"IMG_3820.jpg"],[UIImage imageNamed:@"IMG_3821.jpg"],[UIImage imageNamed:@"IMG_3822.jpg"],[UIImage imageNamed:@"IMG_3823.jpg"],[UIImage imageNamed:@"IMG_3824.jpg"],[UIImage imageNamed:@"IMG_3825.jpg"],[UIImage imageNamed:@"IMG_3826.jpg"],[UIImage imageNamed:@"IMG_3827.jpg"],[UIImage imageNamed:@"IMG_3828.jpg"],[UIImage imageNamed:@"IMG_3829.jpg"],[UIImage imageNamed:@"IMG_3830.jpg"],[UIImage imageNamed:@"IMG_3831.jpg"],[UIImage imageNamed:@"IMG_3832.jpg"],[UIImage imageNamed:@"IMG_3833.jpg"],[UIImage imageNamed:@"IMG_3834.jpg"],[UIImage imageNamed:@"IMG_3835.jpg"],[UIImage imageNamed:@"IMG_3836.jpg"],[UIImage imageNamed:@"IMG_3837.jpg"],[UIImage imageNamed:@"IMG_3838.jpg"],[UIImage imageNamed:@"IMG_3839.jpg"],[UIImage imageNamed:@"IMG_3840.jpg"],[UIImage imageNamed:@"IMG_3841.jpg"],[UIImage imageNamed:@"IMG_3842.jpg"],[UIImage imageNamed:@"IMG_3843.jpg"],[UIImage imageNamed:@"IMG_3844.jpg"],[UIImage imageNamed:@"IMG_3845.jpg"],[UIImage imageNamed:@"IMG_3846.jpg"],nil]; for (int i = 0; i<imageArr.count; i++) { UIImage *imageNew = imageArr[i]; //设置image的尺寸 CGSize imagesize = imageNew.size; imagesize.height =408; imagesize.width =306; //对图片大小进行压缩-- imageNew = [self imageWithImage:imageNew scaledToSize:imagesize]; [imageArray addObject:imageNew]; } UIButton * button =[UIButton buttonWithType:UIButtonTypeRoundedRect]; [button setFrame:CGRectMake(100,100, 100,50)]; [button setTitle:@"视频合成"forState:UIControlStateNormal]; [button addTarget:self action:@selector(testCompressionSession)forControlEvents:UIControlEventTouchUpInside]; button.backgroundColor = [UIColor redColor]; [self.view addSubview:button]; UIButton * button1 =[UIButton buttonWithType:UIButtonTypeRoundedRect]; [button1 setFrame:CGRectMake(100,200, 100,50)]; [button1 setTitle:@"视频播放"forState:UIControlStateNormal]; [button1 addTarget:self action:@selector(playAction)forControlEvents:UIControlEventTouchUpInside]; button1.backgroundColor = [UIColor redColor]; [self.view addSubview:button1];}//对图片尺寸进行压缩---(UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize{// 新创建的位图上下文 newSize为其大小 UIGraphicsBeginImageContext(newSize);// 对图片进行尺寸的改变 [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];// 从当前上下文中获取一个UIImage对象 即获取新的图片对象 UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); // Return the new image. return newImage;}-(void)testCompressionSession{ //设置mov路径 NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES); NSString *moviePath =[[paths objectAtIndex:0]stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mov",@"test"]]; self.theVideoPath=moviePath; //定义视频的大小320 480 倍数 CGSize size =CGSizeMake(320,480); // [selfwriteImages:imageArr ToMovieAtPath:moviePath withSize:sizeinDuration:4 byFPS:30];//第2中方法 NSError *error =nil;// 转成UTF-8编码 unlink([moviePath UTF8String]); NSLog(@"path->%@",moviePath);// iphone提供了AVFoundation库来方便的操作多媒体设备,AVAssetWriter这个类可以方便的将图像和音频写成一个完整的视频文件 AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:moviePath] fileType:AVFileTypeQuickTimeMovie error:&error]; NSParameterAssert(videoWriter); if(error) NSLog(@"error =%@", [error localizedDescription]); //mov的格式设置 编码格式 宽度 高度 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提供CVPixelBufferPool实例,// 可以使用分配像素缓冲区写入输出文件。使用提供的像素为缓冲池分配通常// 是更有效的比添加像素缓冲区分配使用一个单独的池 AVAssetWriterInputPixelBufferAdaptor *adaptor =[AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput sourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary]; NSParameterAssert(writerInput); NSParameterAssert([videoWriter canAddInput:writerInput]); if ([videoWriter canAddInput:writerInput]) { NSLog(@"11111"); } else { NSLog(@"22222"); } [videoWriter addInput:writerInput]; [videoWriter startWriting]; [videoWriter startSessionAtSourceTime:kCMTimeZero]; //合成多张图片为一个视频文件 dispatch_queue_t dispatchQueue =dispatch_queue_create("mediaInputQueue",NULL); int __block frame =0; [writerInput requestMediaDataWhenReadyOnQueue:dispatchQueue usingBlock:^{ while([writerInput isReadyForMoreMediaData]) { if(++frame >=[imageArray count]*10) { [writerInput markAsFinished]; [videoWriter finishWriting]; // [videoWriterfinishWritingWithCompletionHandler:nil]; break; } CVPixelBufferRef buffer =NULL; int idx =frame/10; NSLog(@"idx==%d",idx); buffer = (CVPixelBufferRef)[self pixelBufferFromCGImage:[[imageArray objectAtIndex:idx] CGImage] size:size]; if (buffer) { if(![adaptor appendPixelBuffer:buffer withPresentationTime:CMTimeMake(frame,30)])//设置每秒钟播放图片的个数 { NSLog(@"FAIL"); } else { NSLog(@"OK"); } CFRelease(buffer); } } }];}- (CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)image size:(CGSize)size{ NSDictionary *options =[NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES],kCVPixelBufferCGImageCompatibilityKey, [NSNumber numberWithBool:YES],kCVPixelBufferCGBitmapContextCompatibilityKey,nil]; CVPixelBufferRef pxbuffer =NULL; CVReturn status =CVPixelBufferCreate(kCFAllocatorDefault,size.width,size.height,kCVPixelFormatType_32ARGB,(__bridge CFDictionaryRef) options,&pxbuffer); NSParameterAssert(status ==kCVReturnSuccess && pxbuffer !=NULL); CVPixelBufferLockBaseAddress(pxbuffer,0); void *pxdata =CVPixelBufferGetBaseAddress(pxbuffer); NSParameterAssert(pxdata !=NULL); CGColorSpaceRef rgbColorSpace=CGColorSpaceCreateDeviceRGB();// 当你调用这个函数的时候,Quartz创建一个位图绘制环境,也就是位图上下文。当你向上下文中绘制信息时,Quartz把你要绘制的信息作为位图数据绘制到指定的内存块。一个新的位图上下文的像素格式由三个参数决定:每个组件的位数,颜色空间,alpha选项 CGContextRef context =CGBitmapContextCreate(pxdata,size.width,size.height,8,4*size.width,rgbColorSpace,kCGImageAlphaPremultipliedFirst); NSParameterAssert(context); //使用CGContextDrawImage绘制图片 这里设置不正确的话 会导致视频颠倒// 当通过CGContextDrawImage绘制图片到一个context中时,如果传入的是UIImage的CGImageRef,因为UIKit和CG坐标系y轴相反,所以图片绘制将会上下颠倒 CGContextDrawImage(context,CGRectMake(0,0,CGImageGetWidth(image),CGImageGetHeight(image)), image); // 释放色彩空间 CGColorSpaceRelease(rgbColorSpace); // 释放context CGContextRelease(context); // 解锁pixel buffer CVPixelBufferUnlockBaseAddress(pxbuffer,0); return pxbuffer;}//播放-(void)playAction{ NSLog(@"************%@",self.theVideoPath); NSURL *sourceMovieURL = [NSURL fileURLWithPath:self.theVideoPath]; AVAsset *movieAsset = [AVURLAsset URLAssetWithURL:sourceMovieURL options:nil]; AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:movieAsset]; AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem]; AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player]; playerLayer.frame = self.view.layer.bounds; playerLayer.videoGravity = AVLayerVideoGravityResizeAspect; [self.view.layer addSublayer:playerLayer]; [player play];}
注意事项: 我这里的图片是手机直接进行拍的, 直接拍的图片不进行压缩的话, 合成视频的时间会很长,
这里我进行压缩后合成, 时间会很短 35张图片进行合成 差不多3秒左右
1 0
- IOS多张图片合成一个视频
- IOS多张图片合成一个视频
- IOS多张图片合成一个视频
- IOS多张图片合成一个视频
- iOS多张图片合成一个视频
- IOS多张图片合成一个视频
- iOS多张图片合成一个视频
- iOS 多张图片合成视频
- iOS多张图片合成一个视频文件
- iOS多张图片合成一个视频文件
- iOS多张图片合成一个视频文件
- iOS多张图片合成一个视频文件
- iOS开发图片合成,多张图片合成一张图片
- iOS代码实现两张图片合成一个
- iOS代码实现两张图片合成一个
- 多张图片合成连续动画实现(IOS)
- IOS:如何使用多张图片合成GIF
- 多张图片合成连续动画实现(IOS)
- iOS学习笔记(2)
- 第4周项目5 (2) 用递归方法求解
- kali 2.0中启动带数据库支持的MSF方式
- STM32系列第13篇--OLED
- Nightmare
- IOS多张图片合成一个视频
- 第三周练习 递归1
- NY311 完全背包问题
- 数据库知识汇总
- Red and Black(杭电oj1312)
- Android 高清加载巨图方案 拒绝压缩图片
- The type ActionBarActivity is deprecated
- BZOJ1641Cow Hurdles 奶牛跨栏
- Integer valueOf