使用GPUIMage 添加圖片贬养、文字和gif水印

#import "ViewController.h"
#import "GPUImage.h"
#import <AssetsLibrary/ALAssetsLibrary.h>

@interface ViewController ()
@property (nonatomic , strong) UILabel  *mLabel;
@end


@implementation ViewController
{
GPUImageMovie *movieFile;
GPUImageOutput<GPUImageInput> *filter;
GPUImageMovieWriter *movieWriter;
NSArray * _gifImages;
int _currenIndex;
NSTimeInterval _duration;
}

- (void)viewDidLoad {
[super viewDidLoad];
GPUImageView *filterView = [[GPUImageView alloc] initWithFrame:self.view.frame];
self.view = filterView;

self.mLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 100, 100)];
self.mLabel.textColor = [UIColor redColor];
[self.view addSubview:self.mLabel];

// 濾鏡
filter = [[GPUImageNormalBlendFilter alloc] init];

// [(GPUImageDissolveBlendFilter *)filter setMix:0.5];

// 播放
NSURL *sampleURL = [[NSBundle mainBundle] URLForResource:@"abc" withExtension:@"mp4"];
AVAsset *asset = [AVAsset assetWithURL:sampleURL];
CGSize size = self.view.bounds.size;
movieFile = [[GPUImageMovie alloc] initWithAsset:asset];
movieFile.runBenchmark = YES;
movieFile.playAtActualSpeed = YES;

// 水印
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
label.text = @"我是水印";
label.font = [UIFont systemFontOfSize:30];
label.textColor = [UIColor redColor];
[label sizeToFit];
UIImage *image = [UIImage imageNamed:@"watermark.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame= CGRectMake(0, 0, 40, 40);
UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, size.height, size.width)];
subView.backgroundColor = [UIColor clearColor];
imageView.center = CGPointMake(subView.bounds.size.width / 2, subView.bounds.size.height / 2+80);
[subView addSubview:imageView];
[subView addSubview:label];


NSString *path = [[NSBundle mainBundle] pathForResource:@"lunchGif的副本.gif" ofType:nil] ;
NSData *imageData = [NSData dataWithContentsOfFile:path];

_gifImages = [NSArray array];
_gifImages = [self praseGIFDataToImageArray:imageData];
_duration = [self durationForGifData:imageData];
_currenIndex = 0;
UIImage *image1 = _gifImages[_currenIndex];
UIImageView *imageV = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, image1.size.width*0.3, image1.size.height *0.3)];
imageV.backgroundColor = [UIColor orangeColor];

imageV.image = _gifImages[_currenIndex];
imageView.contentMode = UIViewContentModeScaleAspectFit;
[subView addSubview:imageV];

GPUImageUIElement *uielement3 = [[GPUImageUIElement alloc] initWithView:subView];

NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.m4v"];
unlink([pathToMovie UTF8String]);
NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie];

movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(640, 480)];

GPUImageFilter* progressFilter = [[GPUImageFilter alloc] init];
[movieFile addTarget:progressFilter];
[progressFilter addTarget:filter];
[uielement3 addTarget:filter];


movieWriter.shouldPassthroughAudio = YES;
movieFile.audioEncodingTarget = movieWriter;
[movieFile enableSynchronizedEncodingUsingMovieWriter:movieWriter];
// 顯示到界面
[filter addTarget:filterView];
[filter addTarget:movieWriter];


[movieWriter startRecording];
[movieFile startProcessing];


CADisplayLink* dlink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateProgress)];
[dlink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[dlink setPaused:NO];

__weak typeof(self) weakSelf = self;

[progressFilter setFrameProcessingCompletionBlock:^(GPUImageOutput *output, CMTime time) {
    dispatch_async(dispatch_get_main_queue(), ^{

        _currenIndex ++;
          imageV.image = _gifImages[_currenIndex];
          if (_currenIndex == _gifImages.count -1) {

              _currenIndex = 0;
          }
          [uielement3 update];

    });
    [uielement3 updateWithTimestamp:time];
}];

[movieWriter setCompletionBlock:^{
    __strong typeof(self) strongSelf = weakSelf;
    [strongSelf->filter removeTarget:strongSelf->movieWriter];
    [strongSelf->movieWriter finishRecording];
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(pathToMovie))
    {
        [library writeVideoAtPathToSavedPhotosAlbum:movieURL completionBlock:^(NSURL *assetURL, NSError *error)
         {
             dispatch_async(dispatch_get_main_queue(), ^{
                 
                 if (error) {
                     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"視頻保存失敗" message:nil
                                                                    delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
                     [alert show];
                 } else {
                     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"視頻保存成功" message:nil
                                                                    delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
                     [alert show];
                 }
             });
         }];
    }
    else {
        NSLog(@"error mssg)");
    }
  }];
}



- (void)updateProgress
{
    self.mLabel.text = [NSString stringWithFormat:@"Progress:%d%%", (int)(movieFile.progress * 100)];
    [self.mLabel sizeToFit];
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}


 - (void)didReceiveMemoryWarning
  {
  [super didReceiveMemoryWarning];
}


//gif 轉(zhuǎn)數(shù)組拆撼、
-(NSMutableArray *)praseGIFDataToImageArray:(NSData *)data;
{
NSMutableArray *frames = [[NSMutableArray alloc] init];
CGImageSourceRef src = CGImageSourceCreateWithData((CFDataRef)data, NULL);
CGFloat animationTime = 0.f;
if (src) {
    size_t l = CGImageSourceGetCount(src);
    frames = [NSMutableArray arrayWithCapacity:l];
    for (size_t i = 0; i < l; i++) {
        CGImageRef img = CGImageSourceCreateImageAtIndex(src, i, NULL);
        NSDictionary *properties = (NSDictionary *)CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(src, i, NULL));
        NSDictionary *frameProperties = [properties objectForKey:(NSString *)kCGImagePropertyGIFDictionary];
        NSNumber *delayTime = [frameProperties objectForKey:(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
        animationTime += [delayTime floatValue];
        if (img) {
            [frames addObject:[UIImage imageWithCGImage:img]];
            CGImageRelease(img);
        }
    }
    CFRelease(src);
}
return frames;
}

//獲取gif圖片的總時(shí)長(zhǎng)和循環(huán)次數(shù)
- (NSTimeInterval)durationForGifData:(NSData *)data{
//將GIF圖片轉(zhuǎn)換成對(duì)應(yīng)的圖片源
CGImageSourceRef gifSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
//獲取其中圖片源個(gè)數(shù),即由多少幀圖片組成
size_t frameCout = CGImageSourceGetCount(gifSource);
//定義數(shù)組存儲(chǔ)拆分出來(lái)的圖片
NSMutableArray* frames = [[NSMutableArray alloc] init];
NSTimeInterval totalDuration = 0;
for (size_t i=0; i<frameCout; i++) {
    //從GIF圖片中取出源圖片
    CGImageRef imageRef = CGImageSourceCreateImageAtIndex(gifSource, i, NULL);
    //將圖片源轉(zhuǎn)換成UIimageView能使用的圖片源
    UIImage* imageName = [UIImage imageWithCGImage:imageRef];
    //將圖片加入數(shù)組中
    [frames addObject:imageName];
    NSTimeInterval duration = [self gifImageDeleyTime:gifSource index:i];
    totalDuration += duration;
    CGImageRelease(imageRef);
}

 //獲取循環(huán)次數(shù)
NSInteger loopCount;//循環(huán)次數(shù)
CFDictionaryRef properties = CGImageSourceCopyProperties(gifSource, NULL);
if (properties) {
    CFDictionaryRef gif = CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary);
    if (gif) {
        CFTypeRef loop = CFDictionaryGetValue(gif, kCGImagePropertyGIFLoopCount);
        if (loop) {
     //如果loop == NULL郭变,表示不循環(huán)播放拓巧,當(dāng)loopCount  == 0時(shí),表示無(wú)限循環(huán)思币;
            CFNumberGetValue(loop, kCFNumberNSIntegerType, &loopCount);
  };
    }
}

CFRelease(gifSource);
return totalDuration;
}

//獲取GIF圖片每幀的時(shí)長(zhǎng)
- (NSTimeInterval)gifImageDeleyTime:(CGImageSourceRef)imageSource index:(NSInteger)index {
 NSTimeInterval duration = 0;
 CFDictionaryRef imageProperties =     CGImageSourceCopyPropertiesAtIndex(imageSource, index, NULL);
 if (imageProperties) {
   CFDictionaryRef gifProperties;
   BOOL result = CFDictionaryGetValueIfPresent(imageProperties, kCGImagePropertyGIFDictionary, (const void **)&gifProperties);
   if (result) {
       const void *durationValue;
       if (CFDictionaryGetValueIfPresent(gifProperties, kCGImagePropertyGIFUnclampedDelayTime, &durationValue)) {
           duration = [(__bridge NSNumber *)durationValue doubleValue];
           if (duration < 0) {
               if (CFDictionaryGetValueIfPresent(gifProperties, kCGImagePropertyGIFDelayTime, &durationValue)) {
                   duration = [(__bridge NSNumber *)durationValue doubleValue];
               }
           }
       }
   }
 }

 return duration;
}

@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鹿响,一起剝皮案震驚了整個(gè)濱河市羡微,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌惶我,老刑警劉巖妈倔,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異指孤,居然都是意外死亡启涯,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門恃轩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)结洼,“玉大人,你說(shuō)我怎么就攤上這事叉跛∷扇蹋” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵筷厘,是天一觀的道長(zhǎng)鸣峭。 經(jīng)常有香客問我,道長(zhǎng)酥艳,這世上最難降的妖魔是什么摊溶? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮充石,結(jié)果婚禮上莫换,老公的妹妹穿的比我還像新娘。我一直安慰自己骤铃,他們只是感情好拉岁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惰爬,像睡著了一般喊暖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上撕瞧,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天陵叽,我揣著相機(jī)與錄音,去河邊找鬼风范。 笑死咨跌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的硼婿。 我是一名探鬼主播锌半,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了刊殉?” 一聲冷哼從身側(cè)響起殉摔,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎记焊,沒想到半個(gè)月后逸月,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡遍膜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年碗硬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓢颅。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡恩尾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出挽懦,到底是詐尸還是另有隱情翰意,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布信柿,位于F島的核電站冀偶,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏渔嚷。R本人自食惡果不足惜进鸠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望形病。 院中可真熱鬧堤如,春花似錦、人聲如沸窒朋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)侥猩。三九已至,卻和暖如春抵赢,著一層夾襖步出監(jiān)牢的瞬間欺劳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工铅鲤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留划提,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓邢享,卻偏偏與公主長(zhǎng)得像鹏往,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子骇塘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

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