用GPUImage来给视频加入水印

这篇博客原计划是在去年10月末写完的。。。但是因为之后开始人生第一次工作。。就一直拖到了现在。。。跳票了真是十分抱歉(鞠躬ing)

那么如题,主要说一下怎么用GPUImage这个库来给视频添加水印。

  1. 先要了解, 水印其实就是一张图片,给视频加上水印,其实就是给这个视频的每一帧叠加上一张图片,而且图片的位置和大小都是固定的,这样思路就很清晰了。

  2. 因为是叠加,所以需要用到blendFilter(blendFilter有很多种,我这里就直接用了GPUImageAlphaBlendFilter,主要用来做半透明的混合的,简直是水印专用!)

  3. 因为某些水印是带有动画效果的,也就是随着视频的播放,水印的位置和大小虽然不变,但是水印的图片(image)可能会改变,这是做动画效果的一种方法;另外的方法当然就是改变位置和大小了。这样的效果可以通过使用GPUImageTransformFilter来制作,通过setAffineTransform:可以改变从GPUImageTransformFilter中流出的图像数据,具体请参考coreAnimation。

下面给出代码:
1.准备工作,导入要编辑的视频

    NSURL *sampleURL = [[NSBundle mainBundle] URLForResource:@"demo1"    
          withExtension:@"mp4"];

    _movieFile = [[GPUImageMovie alloc] initWithURL:sampleURL];
    _movieFile.runBenchmark = YES;
    _movieFile.playAtActualSpeed = NO;

    //获取视频的大小(画面大小),来确定水印的位置和大小;
    AVAsset *fileas = [AVAsset assetWithURL:sampleURL];
    CGSize movieSize = fileas.naturalSize;

2.准备滤镜,因为如果直接使用blendFilter的话会把水印图像直接放大来做叠加,所以这里我用了GPUImageUIElement,设置一个跟视频画面大小一样的View,在这个View里面加入水印的ImageView,调整位置,之后把这个View给添加到视频里面去。

    UIImage *image = [UIImage imageNamed:@"sample01"];
    UIImageView *imv = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 800, 560)];
    [imv setImage:image];
    UIView *vi = [[UIView alloc] initWithFrame:CGRectMake(0, 0, movieSize.width, movieSize.height)];
    vi.backgroundColor = [UIColor clearColor];
    imv.center = CGPointMake(vi.bounds.size.width, vi.bounds.size.height + 80);
    [vi addSubview:imv];

    _landInput = [[GPUImageUIElement alloc] initWithView:vi];
    _landBlendFilter = [[GPUImageAlphaBlendFilter alloc] init];
    //mix即为叠加后的透明度,这里就直接写1.0了
    _landBlendFilter.mix = 1.0f;

给上输出路径,就是编辑好的视频的存放地址

    NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.mp4"];
    unlink([pathToMovie UTF8String]); //如果视频存在,删掉!
    NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie];

这里不知为何,我用GPUImageMovie直接读取出来的视频数据如果target是blendFilter就是nil…..先给一个普通的filter再给blendFilter就没有问题,所以就直接先add到GPUImageBrightnessFilter里面去,设置了亮度为平常程度,就不会有影响了。

    _movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(640.0, 480.0)];
    _movieWriter.transform = CGAffineTransformMakeScale(0.3, 0.3);

    _brightnessFilter = [[GPUImageBrightnessFilter alloc] init];
    _brightnessFilter.brightness = 0.0f;

    [_movieFile addTarget:_brightnessFilter];
    [_brightnessFilter addTarget:_landBlendFilter];
    [_landInput addTarget:_landBlendFilter];

    [_landBlendFilter addTarget:_movieWriter];

如果需要做动画效果的话

[_blendFilter setFrameProcessingCompletionBlock:^(GPUImageOutput *output, CMTime currentTime) {

        //在这里改变水印的位置、大小等属性;
        //直接改imageView的frame就好,修改了记得要update就好
        [weakSelf.landInput update];
    }];

导出视频,写入相册;

    __weak ViewController *weakSelf = self;
    _movieWriter.shouldPassthroughAudio = YES;
    _movieFile.audioEncodingTarget = _movieWriter;
    [_movieFile enableSynchronizedEncodingUsingMovieWriter:_movieWriter];

    [_movieWriter startRecording];
    [_movieFile startProcessing];

    [_movieWriter setCompletionBlock:^{
        [weakSelf.filter removeTarget:weakSelf.movieWriter];
        [weakSelf.movieWriter finishRecording];

        dispatch_async(dispatch_get_main_queue(), ^{

            ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

            [library writeVideoAtPathToSavedPhotosAlbum:[NSURL   
                    fileURLWithPath:pathToMovie] 
                    completionBlock:^(NSURL *assetURL, NSError 
                    *error) {

                dispatch_async(dispatch_get_main_queue(), ^{
                    NSLog(@"---finished!!!!!");

                    [[[UIAlertView alloc] initWithTitle:@"" message:@"已经成功
                    写入相册!" delegate:nil cancelButtonTitle:@"好的" 
                    otherButtonTitles: nil] show];
                });
            }];
        });
    }];

最后给一个效果预览:
这里写图片描述

这里给出Demo的链接:http://pan.baidu.com/s/1eRzfP6a demo传到百度云上面去了,打包的时候把demo里面的视频和图片都去掉了,记得先把要编辑的视频URL给改掉。

猜你喜欢

转载自blog.csdn.net/u1031/article/details/50788093
今日推荐