IOS多張圖片合成一個(gè)視頻

圖片合成視頻

首先需要導(dǎo)入的三個(gè)依賴庫(kù)

AVKit.framework??? MediaPlayer.framework??? AVFoundation.framework

下面代碼中的注釋很清楚, 就不做多解釋, 直接上代碼了

[objc]view plaincopy

#import?"ViewController.h"

#import?

#import?

#import?

@interfaceViewController?()

{

NSMutableArray*imageArr;//未壓縮的圖片

NSMutableArray*imageArray;//經(jīng)過壓縮的圖片

}

@property(nonatomic,strong)NSString*theVideoPath;

@end

@implementationViewController

-?(void)viewDidLoad?{

[superviewDidLoad];

imageArray?=?[[NSMutableArrayalloc]init];

imageArr?=[[NSMutableArrayalloc]initWithObjects:

[UIImageimageNamed:@"IMG_3811.jpg"],[UIImageimageNamed:@"IMG_3812.jpg"],[UIImageimageNamed:@"IMG_3813.jpg"],[UIImageimageNamed:@"IMG_3814.jpg"],[UIImageimageNamed:@"IMG_3815.jpg"],[UIImageimageNamed:@"IMG_3816.jpg"],[UIImageimageNamed:@"IMG_3817.jpg"],[UIImageimageNamed:@"IMG_3818.jpg"],[UIImageimageNamed:@"IMG_3820.jpg"],[UIImageimageNamed:@"IMG_3821.jpg"],[UIImageimageNamed:@"IMG_3822.jpg"],[UIImageimageNamed:@"IMG_3823.jpg"],[UIImageimageNamed:@"IMG_3824.jpg"],[UIImageimageNamed:@"IMG_3825.jpg"],[UIImageimageNamed:@"IMG_3826.jpg"],[UIImageimageNamed:@"IMG_3827.jpg"],[UIImageimageNamed:@"IMG_3828.jpg"],[UIImageimageNamed:@"IMG_3829.jpg"],[UIImageimageNamed:@"IMG_3830.jpg"],[UIImageimageNamed:@"IMG_3831.jpg"],[UIImageimageNamed:@"IMG_3832.jpg"],[UIImageimageNamed:@"IMG_3833.jpg"],[UIImageimageNamed:@"IMG_3834.jpg"],[UIImageimageNamed:@"IMG_3835.jpg"],[UIImageimageNamed:@"IMG_3836.jpg"],[UIImageimageNamed:@"IMG_3837.jpg"],[UIImageimageNamed:@"IMG_3838.jpg"],[UIImageimageNamed:@"IMG_3839.jpg"],[UIImageimageNamed:@"IMG_3840.jpg"],[UIImageimageNamed:@"IMG_3841.jpg"],[UIImageimageNamed:@"IMG_3842.jpg"],[UIImageimageNamed:@"IMG_3843.jpg"],[UIImageimageNamed:@"IMG_3844.jpg"],[UIImageimageNamed:@"IMG_3845.jpg"],[UIImageimageNamed:@"IMG_3846.jpg"],nil];

for(inti?=0;?i

UIImage*imageNew?=?imageArr[i];

//設(shè)置image的尺寸

CGSize?imagesize?=?imageNew.size;

imagesize.height=408;

imagesize.width=306;

//對(duì)圖片大小進(jìn)行壓縮--

imageNew?=?[selfimageWithImage:imageNewscaledToSize:imagesize];

[imageArrayaddObject:imageNew];

}

UIButton*?button?=[UIButtonbuttonWithType:UIButtonTypeRoundedRect];

[buttonsetFrame:CGRectMake(100,100,100,50)];

[buttonsetTitle:@"視頻合成"forState:UIControlStateNormal];

[buttonaddTarget:selfaction:@selector(testCompressionSession)forControlEvents:UIControlEventTouchUpInside];

button.backgroundColor=?[UIColorredColor];

[self.viewaddSubview:button];

UIButton*?button1=[UIButtonbuttonWithType:UIButtonTypeRoundedRect];

[button1setFrame:CGRectMake(100,200,100,50)];

[button1setTitle:@"視頻播放"forState:UIControlStateNormal];

[button1addTarget:selfaction:@selector(playAction)forControlEvents:UIControlEventTouchUpInside];

button1.backgroundColor=?[UIColorredColor];

[self.viewaddSubview:button1];

}

//對(duì)圖片尺寸進(jìn)行壓縮--

-(UIImage*)imageWithImage:(UIImage*)imagescaledToSize:(CGSize)newSize

{

//????新創(chuàng)建的位圖上下文?newSize為其大小

UIGraphicsBeginImageContext(newSize);

//????對(duì)圖片進(jìn)行尺寸的改變

[imagedrawInRect:CGRectMake(0,0,newSize.width,newSize.height)];

//????從當(dāng)前上下文中獲取一個(gè)UIImage對(duì)象??即獲取新的圖片對(duì)象

UIImage*?newImage?=?UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

//?Return?the?new?image.

returnnewImage;

}

-(void)testCompressionSession

{

//設(shè)置mov路徑

NSArray*paths?=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);

NSString*moviePath?=[[pathsobjectAtIndex:0]stringByAppendingPathComponent:[NSStringstringWithFormat:@"%@.mov",@"test"]];

self.theVideoPath=moviePath;

//定義視頻的大小320?480?倍數(shù)

CGSize?size?=CGSizeMake(320,480);

//????????[selfwriteImages:imageArr?ToMovieAtPath:moviePath?withSize:sizeinDuration:4?byFPS:30];//第2中方法

NSError*error?=nil;

//????轉(zhuǎn)成UTF-8編碼

unlink([moviePathUTF8String]);

NSLog(@"path->%@",moviePath);

//?????iphone提供了AVFoundation庫(kù)來方便的操作多媒體設(shè)備驾孔,AVAssetWriter這個(gè)類可以方便的將圖像和音頻寫成一個(gè)完整的視頻文件

AVAssetWriter*videoWriter?=?[[AVAssetWriteralloc]initWithURL:[NSURLfileURLWithPath:moviePath]fileType:AVFileTypeQuickTimeMovieerror:&error];

NSParameterAssert(videoWriter);

if(error)

NSLog(@"error?=%@",?[errorlocalizedDescription]);

//mov的格式設(shè)置?編碼格式?寬度?高度

NSDictionary*videoSettings?=[NSDictionarydictionaryWithObjectsAndKeys:AVVideoCodecH264,AVVideoCodecKey,

[NSNumbernumberWithInt:size.width],AVVideoWidthKey,

[NSNumbernumberWithInt:size.height],AVVideoHeightKey,nil];

AVAssetWriterInput*writerInput?=[AVAssetWriterInputassetWriterInputWithMediaType:AVMediaTypeVideooutputSettings:videoSettings];

NSDictionary*sourcePixelBufferAttributesDictionary?=[NSDictionarydictionaryWithObjectsAndKeys:[NSNumbernumberWithInt:kCVPixelFormatType_32ARGB],kCVPixelBufferPixelFormatTypeKey,nil];

//????AVAssetWriterInputPixelBufferAdaptor提供CVPixelBufferPool實(shí)例,

//????可以使用分配像素緩沖區(qū)寫入輸出文件。使用提供的像素為緩沖池分配通常

//????是更有效的比添加像素緩沖區(qū)分配使用一個(gè)單獨(dú)的池

AVAssetWriterInputPixelBufferAdaptor*adaptor?=[AVAssetWriterInputPixelBufferAdaptorassetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInputsourcePixelBufferAttributes:sourcePixelBufferAttributesDictionary];

NSParameterAssert(writerInput);

NSParameterAssert([videoWritercanAddInput:writerInput]);

if([videoWritercanAddInput:writerInput])

{

NSLog(@"11111");

}

else

{

NSLog(@"22222");

}

[videoWriteraddInput:writerInput];

[videoWriterstartWriting];

[videoWriterstartSessionAtSourceTime:kCMTimeZero];

//合成多張圖片為一個(gè)視頻文件

dispatch_queue_t?dispatchQueue?=dispatch_queue_create("mediaInputQueue",NULL);

int__block?frame?=0;

[writerInputrequestMediaDataWhenReadyOnQueue:dispatchQueueusingBlock:^{

while([writerInputisReadyForMoreMediaData])

{

if(++frame?>=[imageArraycount]*10)

{

[writerInputmarkAsFinished];

[videoWriterfinishWriting];

//??????????????[videoWriterfinishWritingWithCompletionHandler:nil];

break;

}

CVPixelBufferRef?buffer?=NULL;

intidx?=frame/10;

NSLog(@"idx==%d",idx);

buffer?=?(CVPixelBufferRef)[selfpixelBufferFromCGImage:[[imageArrayobjectAtIndex:idx]CGImage]size:size];

if(buffer)

{

if(![adaptorappendPixelBuffer:bufferwithPresentationTime:CMTimeMake(frame,30)])//設(shè)置每秒鐘播放圖片的個(gè)數(shù)

{

NSLog(@"FAIL");

}

else

{

NSLog(@"OK");

}

CFRelease(buffer);

}

}

}];

}

-?(CVPixelBufferRef)pixelBufferFromCGImage:(CGImageRef)imagesize:(CGSize)size

{

NSDictionary*options?=[NSDictionarydictionaryWithObjectsAndKeys:

[NSNumbernumberWithBool:YES],kCVPixelBufferCGImageCompatibilityKey,

[NSNumbernumberWithBool: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);

voidvoid*pxdata?=CVPixelBufferGetBaseAddress(pxbuffer);

NSParameterAssert(pxdata?!=NULL);

CGColorSpaceRef?rgbColorSpace=CGColorSpaceCreateDeviceRGB();

//????當(dāng)你調(diào)用這個(gè)函數(shù)的時(shí)候惯疙,Quartz創(chuàng)建一個(gè)位圖繪制環(huán)境翠勉,也就是位圖上下文。當(dāng)你向上下文中繪制信息時(shí)霉颠,Quartz把你要繪制的信息作為位圖數(shù)據(jù)繪制到指定的內(nèi)存塊对碌。一個(gè)新的位圖上下文的像素格式由三個(gè)參數(shù)決定:每個(gè)組件的位數(shù),顏色空間蒿偎,alpha選項(xiàng)

CGContextRef?context?=CGBitmapContextCreate(pxdata,size.width,size.height,8,4*size.width,rgbColorSpace,kCGImageAlphaPremultipliedFirst);

NSParameterAssert(context);

//使用CGContextDrawImage繪制圖片??這里設(shè)置不正確的話?會(huì)導(dǎo)致視頻顛倒

//????當(dāng)通過CGContextDrawImage繪制圖片到一個(gè)context中時(shí)朽们,如果傳入的是UIImage的CGImageRef,因?yàn)閁IKit和CG坐標(biāo)系y軸相反诉位,所以圖片繪制將會(huì)上下顛倒

CGContextDrawImage(context,CGRectMake(0,0,CGImageGetWidth(image),CGImageGetHeight(image)),?image);

//?釋放色彩空間

CGColorSpaceRelease(rgbColorSpace);

//?釋放context

CGContextRelease(context);

//?解鎖pixel?buffer

CVPixelBufferUnlockBaseAddress(pxbuffer,0);

returnpxbuffer;

}

//播放

-(void)playAction

{

NSLog(@"************%@",self.theVideoPath);

NSURL*sourceMovieURL?=?[NSURLfileURLWithPath:self.theVideoPath];

AVAsset*movieAsset?=?[AVURLAssetURLAssetWithURL:sourceMovieURLoptions:nil];

AVPlayerItem*playerItem?=?[AVPlayerItemplayerItemWithAsset:movieAsset];

AVPlayer*player?=?[AVPlayerplayerWithPlayerItem:playerItem];

AVPlayerLayer*playerLayer?=?[AVPlayerLayerplayerLayerWithPlayer:player];

playerLayer.frame=self.view.layer.bounds;

playerLayer.videoGravity=?AVLayerVideoGravityResizeAspect;

[self.view.layeraddSublayer:playerLayer];

[playerplay];

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末骑脱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子苍糠,更是在濱河造成了極大的恐慌叁丧,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件椿息,死亡現(xiàn)場(chǎng)離奇詭異歹袁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)寝优,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門条舔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人乏矾,你說我怎么就攤上這事孟抗∏ㄑ睿” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵凄硼,是天一觀的道長(zhǎng)铅协。 經(jīng)常有香客問我,道長(zhǎng)摊沉,這世上最難降的妖魔是什么狐史? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮说墨,結(jié)果婚禮上骏全,老公的妹妹穿的比我還像新娘。我一直安慰自己尼斧,他們只是感情好姜贡,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著棺棵,像睡著了一般楼咳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上烛恤,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天母怜,我揣著相機(jī)與錄音,去河邊找鬼缚柏。 笑死糙申,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的船惨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼缕陕,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼粱锐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起扛邑,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤怜浅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蔬崩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恶座,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年沥阳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了跨琳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡桐罕,死狀恐怖脉让,靈堂內(nèi)的尸體忽然破棺而出桂敛,到底是詐尸還是另有隱情,我是刑警寧澤溅潜,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布术唬,位于F島的核電站,受9級(jí)特大地震影響滚澜,放射性物質(zhì)發(fā)生泄漏粗仓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一设捐、第九天 我趴在偏房一處隱蔽的房頂上張望借浊。 院中可真熱鬧,春花似錦挡育、人聲如沸巴碗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽橡淆。三九已至,卻和暖如春母赵,著一層夾襖步出監(jiān)牢的瞬間逸爵,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工凹嘲, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留师倔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓周蹭,卻偏偏與公主長(zhǎng)得像趋艘,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子凶朗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 這個(gè) 給我的感覺就像是 PPT 播放一樣棚愤。這里找了一些資料搓萧,學(xué)習(xí)視頻合成方面的知識(shí)。 一:圖片和視頻的合成: @i...
    icc_tips閱讀 8,229評(píng)論 10 25
  • --繪圖與濾鏡全面解析 概述 在iOS中可以很容易的開發(fā)出絢麗的界面效果宛畦,一方面得益于成功系統(tǒng)的設(shè)計(jì)瘸洛,另一方面得益...
    韓七夏閱讀 2,717評(píng)論 2 10
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜次和,今天將帶大家一窺iOS動(dòng)畫全貌反肋。在這里你可以看...
    F麥子閱讀 5,104評(píng)論 5 13
  • 攻城獅GG閱讀 225評(píng)論 0 1
  • "媽媽,有僵尸踏施。"起床第一句話囚玫,姐姐如此說喧锦,眼睛都沒睜開! “哦抓督?哪里有僵尸燃少?”我一臉懵,她打哪聽來的這個(gè)詞铃在。 “...
    東盼閱讀 517評(píng)論 0 50