ios去水印的app视频水印app有哪些

iOS 给视频添加水印 动画 背景音乐 - 简书
iOS 给视频添加水印 动画 背景音乐
视频处理主要是用到以下这几个类AVMutableComposition、AVMutableVideoComposition、AVMutableAudioMix、AVMutableVideoCompositionInstruction、AVMutableVideoCompositionLayerInstruction、AVAssetExportSession 等。其中 AVMutableComposition 可以用来操作音频和视频的组合,AVMutableVideoComposition 可以用来对视频进行操作,AVMutableAudioMix 类是给视频添加音频的,AVMutableVideoCompositionInstruction和AVMutableVideoCompositionLayerInstruction 一般都是配合使用,用来给视频添加水印或者旋转视频方向,AVAssetExportSession 是用来进行视频导出操作的。需要值得注意的是当App进入后台之后,会对使用到GPU的代码操作进行限制,会造成崩溃,而视频处理这些功能多数会使用到GPU,所以需要做对应的防错处理。在这里我会使用Apple的官方Demo “AVSimpleEditoriOS” 作为讲解案例,该案例采用Command设计模式来组织代码,其中基类的AVSECommand包含了一些各个子类Command共用的属性。本文就视频相关操作做简要介绍,说明一些相关的操作,并标注一些重点代码,希望本文可以起到抛砖引玉的效果,让大家对视频剪辑处理有个初步印象,然后可以根据Apple官方Demo的内容进行相应的修改。大家可以下载相应的Apple官方Demo运行查看结果。第一节:给视频添加水印和背景边框今天第一节先讲解如何为一个视频添加边框和动画,首先说明的是,这种边框和动画并不能直接修改视频的某一帧给他增加边框或者产生动画效果,这种动画更像是给视频的上面加一个calayer,然后控制这个layer产生动画效果。因为具体到某一帧的这种操作不是iphone应该做的他也做不到。我们先来看一张图,了解一下给video增加动画的原理。
你可以看到videoLayer这个东西,其实这个layer就是负责显示我们的视频,和他同级的是一个叫animationLayer的东西,我们能够掌控并且玩出花样的其实是这个叫animationLayer的东西,因为这个animationLayer可以由我们自己创建。其实很简单,和我们videoLayer同级别的layer叫animationLayer(就是background),他们共同有个父类叫做parentLayer,那么增加边框无非是把animationLayer这个layer找个边框的图片,然后把他放到videoLayer的下面,然后把videoLayer(crop也就是裁剪)的尺寸控制到刚好能显示animationLayer的四边,这样,不就成了带边框的效果么。简单点讲就是 把裁剪好的视频 videoLayer放在了 背景上然后再加入到parentLayer里 。视频添加水印和背景边框具体步骤1.拿到视频和音频资源2.创建AVMutableComposition对象3.往AVMutableComposition对象添加视频资源,同时设置视频资源的时间段和插入点4.往AVMutableComposition对象添加音频资源,同时设置音频资源的时间段和插入点5.创建视频组合器对象 AVMutableVideoComposition 并设置frame和渲染宽高6.创建视频组合器指令对象,设置指令的作用范围7.创建视频组合器图层指令对象,设置指令的作用范围8.视频组合器图层指令对象 放入 视频组合器指令对象中9.视频组合器指令对象放入视频组合器对象10.创建水印图层Layer并设置frame和水印的位置,并将水印加入视频组合器中具体代码实现
- (void)performWithAsset:(AVAsset*)asset withImageNamed:(NSString*)imgName withColorName:(NSString*)color withMusicName:(NSString *)musicName with:(CGRect)photoSize{
CGSize videoS
// 获取视频资源和音频资源
AVAssetTrack *assetVideoTrack =
AVAssetTrack *assetAudioTrack =
// Check if the asset contains video and audio tracks
if ([[asset tracksWithMediaType:AVMediaTypeVideo] count] != 0) {
assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo][0];
if ([[asset tracksWithMediaType:AVMediaTypeAudio] count] != 0) {
assetAudioTrack = [asset tracksWithMediaType:AVMediaTypeAudio][0];
CMTime insertionPoint = kCMTimeZ
NSError *error =
// 创建组合器对象并添加视频资源和音频资源
// Create a composition with the given asset and insert audio and video tracks into it from the asset
if(!self.mutableComposition) {
// Check if a composition already exists, else create a composition using the input asset
self.mutableComposition = [AVMutableComposition composition];
// Insert the video and audio tracks from AVAsset
if (assetVideoTrack != nil) {
AVMutableCompositionTrack *compositionVideoTrack = [self.mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:assetVideoTrack atTime:insertionPoint error:&error];
if (assetAudioTrack != nil) {
AVMutableCompositionTrack *compositionAudioTrack = [self.mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:assetAudioTrack atTime:insertionPoint error:&error];
创建一个和视频相同大小的背景层
if ([[self.mutableComposition tracksWithMediaType:AVMediaTypeVideo] count] != 0) {
if(!self.mutableVideoComposition) {
self.mutableVideoComposition = [AVMutableVideoComposition videoComposition];
AVMutableVideoCompositionInstruction *passThroughInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
AVAssetTrack *videoTrack = [self.mutableComposition tracksWithMediaType:AVMediaTypeVideo][0];
AVMutableVideoCompositionLayerInstruction *passThroughLayer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
//对视频大小进行裁剪,我这里是将视频裁剪成 等宽高的正方形
CGSize renderSize = CGSizeMake(0, 0);
renderSize.width = MAX(renderSize.width, videoTrack.naturalSize.height);
renderSize.height = MAX(renderSize.height, videoTrack.naturalSize.width);
CGFloat renderW = MIN(renderSize.width, renderSize.height);
rate = renderW / MIN(videoTrack.naturalSize.width, videoTrack.naturalSize.height);
//对视频的方向进行处理
CGAffineTransform translateToC
CGAffineTransform mixedT
NSInteger degrees = [self degressFromVideoFileWithURL:asset];
if (degrees == 0) {
if (videoTrack.naturalSize.width == videoTrack.naturalSize.height) {
translateToCenter = CGAffineTransformMakeTranslation(0.0, 0.0);
translateToCenter = CGAffineTransformMakeTranslation(-140.0, 0.0);
mixedTransform = CGAffineTransformRotate(translateToCenter,0);
if(degrees == 90){
//顺时针旋转90°
NSLog(@"视频旋转90度,home按键在左");
translateToCenter = CGAffineTransformMakeTranslation(videoTrack.naturalSize.height, -240);
mixedTransform = CGAffineTransformRotate(translateToCenter,M_PI_2);
}else if(degrees == 180){
//顺时针旋转180°
NSLog(@"视频旋转180度,home按键在上");
translateToCenter = CGAffineTransformMakeTranslation(videoTrack.naturalSize.width, videoTrack.naturalSize.height);
mixedTransform = CGAffineTransformRotate(translateToCenter,M_PI);
}else if(degrees == 270){
//顺时针旋转270°
NSLog(@"视频旋转270度,home按键在右");
translateToCenter = CGAffineTransformMakeTranslation(0.0, videoTrack.naturalSize.width);
mixedTransform = CGAffineTransformRotate(translateToCenter,M_PI_2*3.0);
//将处理好的视频赋值给AVMutableVideoCompositionLayerInstruction
[passThroughLayer setTransform:mixedTransform atTime:kCMTimeZero];
[passThroughLayer setOpacity:0.0 atTime:[asset duration]];
//然后将处理好的AVMutableVideoCompositionLayerInstruction赋值给AVMutableVideoCompositionInstruction
passThroughInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, [asset duration]);
passThroughInstruction.layerInstructions = @[passThroughLayer];
//创建 video composition
self.mutableVideoComposition.instructions = @[passThroughInstruction];
self.mutableVideoComposition.frameDuration = CMTimeMake(1, 30); // 30 fps
self.mutableVideoComposition.renderSize = CGSizeMake(renderW, renderW);
videoSize = self.mutableVideoComposition.renderS
//添加背景
self.watermarkLayer = [self watermarkLayerForSize:videoSize withImageNamed:imgName withColorName:color];
// Step 3 发送通知到你想要处理的界面
// Notify AVSEViewController about add watermark operation completion
[[NSNotificationCenter defaultCenter] postNotificationName:AVSEEditCommandCompletionNotification object:self];
// 这里执行添加背景边框 和 水印的 layer
- (CALayer*)watermarkLayerForSize:(CGSize)videoSize withImageNamed:(NSString*)imgName withColorName:(NSString *)color{
// Create a layer for the title
CALayer *titleLayer = [CALayer layer];
titleLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height);//此处的Frame为视频展示试图的大小
titleLayer.masksToBounds =
UIImage *image = [UIImage imageNamed:imgName];
titleLayer.contents = (id)image.CGI
titleLayer.position = CGPointMake(videoSize.width/2, videoSize.height/2);
//还能给背景设置样式和颜色
//do something...
return titleL
- (void)exportWillBegin{
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
if (self.backGroundLayer) {
videoLayer.frame = CGRectMake(20, 20, self.videoComposition.renderSize.width - 40, self.videoComposition.renderSize.height - 40);
videoLayer.frame = CGRectMake(0, 0, self.videoComposition.renderSize.width, self.videoComposition.renderSize.height);
parentLayer.frame = CGRectMake(0, 0, self.videoComposition.renderSize.width, self.videoComposition.renderSize.height);
//这里是先添加背景backgroundLayer,然后再添加videoLayer,那么视频就会在背景上了。
//而添加水印则是相反的,我们把overlayLayer放在了videolayer的上面,所以水印总是显示在视频之上的。
[parentLayer addSublayer:backgroundLayer];
[parentLayer addSublayer:videoLayer];
//添加水印到视频组合器里
self.videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
//之后导出就可以了
第二节:视频添加动画添加动画的原理 和 添加水印是一样的
- (CALayer*)watermarkLayerForSize:(CGSize)videoSize withImageNamed:(NSString*)imgName withColorName:(NSString *)color{
// Create a layer for the title
CALayer *overlayLayer1 = [CALayer layer];
[overlayLayer1 setContents:(id)[animationImage CGImage]];
overlayLayer1.frame = CGRectMake(size.width/2-64, size.height/2 + 200, 128, 128);
[overlayLayer1 setMasksToBounds:YES];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
animation.duration=2.0;
animation.repeatCount=5;
animation.autoreverses=YES;
// rotate from 0 to 360
animation.fromValue=[NSNumber numberWithFloat:0.0];
animation.toValue=[NSNumber numberWithFloat:(2.0 * M_PI)];
animation.beginTime = AVCoreAnimationBeginTimeAtZ
//注意一定要设置开始时间不然不显示
[overlayLayer1 addAnimation:animation forKey:@"rotation"];
return overlayLayer1;
第三节:视频添加音频1.拿到视频和音频资源2.创建AVMutableComposition对象3.往AVMutableComposition对象添加视频资源,同时设置视频资源的时间段和插入点4.往AVMutableComposition对象添加音频资源,同时设置音频资源的时间段和插入点5.往AVMutableComposition对象添加要追加的音频资源,同时设置音频资源的时间段,插入点和混合模式
- (void)performWithAsset:(AVAsset*)asset withImageNamed:(NSString*)imgName withMusicName:(NSString *)musicName
AVAssetTrack *assetVideoTrack =
AVAssetTrack *assetAudioTrack =
// Check if the asset contains video and audio tracks
拿到视频和音频资源
if ([[asset tracksWithMediaType:AVMediaTypeVideo] count] != 0) {
assetVideoTrack = [asset tracksWithMediaType:AVMediaTypeVideo][0];
if ([[asset tracksWithMediaType:AVMediaTypeAudio] count] != 0) {
assetAudioTrack = [asset tracksWithMediaType:AVMediaTypeAudio][0];
NSError *error =
NSArray *Arr = [NSArray array];
Arr = [musicName componentsSeparatedByString:@"."];
NSString *audioURL = [[NSBundle mainBundle] pathForResource:[Arr firstObject] ofType:[Arr lastObject]];
AVAsset *audioAsset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:audioURL] options:nil];
AVAssetTrack *newAudioTrack = [audioAsset tracksWithMediaType:AVMediaTypeAudio][0];
创建AVMutableComposition对象
if (!self.mutableComposition) {
// Check whether a composition has already been created, i.e, some other tool has already been applied.
new composition组合器
self.mutableComposition = [AVMutableComposition composition];
// Add tracks to composition from the input video asset
if (assetVideoTrack != nil) {
往AVMutableComposition对象添加视频资源,同时设置视频资源的时间段和插入点
AVMutableCompositionTrack *compositionVideoTrack = [self.mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:assetVideoTrack atTime:kCMTimeZero error:&error];
if (assetAudioTrack != nil) {
往AVMutableComposition对象添加音频资源, 同时设置音频资源的时间段和插入点
AVMutableCompositionTrack *compositionAudioTrack = [self.mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:assetAudioTrack atTime:kCMTimeZero error:&error];
添加音频资源到composition
AVMutableCompositionTrack *customAudioTrack = [self.mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[customAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [self.mutableComposition duration]) ofTrack:newAudioTrack atTime:kCMTimeZero error:&error];
设置添加资源中的音频时间段,并与原有视频中的音频混合
AVMutableAudioMixInputParameters *mixParameters = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:customAudioTrack];
[mixParameters setVolumeRampFromStartVolume:1 toEndVolume:0 timeRange:CMTimeRangeMake(kCMTimeZero, self.mutableComposition.duration)];
self.mutableAudioMix = [AVMutableAudioMix audioMix];
self.mutableAudioMix.inputParameters = @[mixParameters];
// Step 5 发送通知到你想要处理的界面,这里完成之后就可以直接导出了,因为音乐已经添加到对于的视频上了
[[NSNotificationCenter defaultCenter] postNotificationName:AVSEEditCommandCompletionNotification object:self];
需要注意的是:如果你的视频在界面上进行展示了,那在添加了音乐之后就要去刷新UI。我这里使用的是AVPlayer来进行播放
//视频播放试图
- (void)video:(NSString *)videoPath{
NSURL *url = [NSURL fileURLWithPath:videoPath];
self.player = [AVPlayer playerWithURL:url];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
playerLayer.bounds = self.photo.
playerLayer.position = CGPointMake(self.photo.bounds.size.width/2, self.photo.bounds.size.height/2);
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectF//视频填充模式
[self.photo.layer addSublayer:playerLayer];
[self.player play];
[self reloadPlayerViewWithMusic];
- (void)playbackFinished:(NSNotification *)n{
//注册的通知
可以自动把 AVPlayerItem 对象传过来,只要接收一下就OK
AVPlayerItem * playerItem = [n object];
//关键代码
[playerItem seekToTime:kCMTimeZero];
[self.player play];
NSLog(@"重播");
// 添加音乐后 刷新视频播放器
- (void)reloadPlayerViewWithMusic{
mutableAudioMix = self.audioM
AVPlayerItem * playerItem = [AVPlayerItem playerItemWithAsset:self.composition];
判断是否 有音频文件
if(self.videoComposition && self.audioMix){
playerItem.videoComposition = self.videoC
playerItem.audioMix = self.audioM
[self.player replaceCurrentItemWithPlayerItem:playerItem];
第五节:视频导出1.创建输出路径2.根据AVMutableComposition对象创建AVAssetExportSession视频导出对象3.设置AVAssetExportSession的AVMutableVideoComposition对象,AVMutableAudioMix对象,视频导出路径,视频导出格式4.异步导出视频,根据导出结果做对应处理。- (void)performWithAsset:(AVAsset*)asset withImageNamed:(NSString*)imgName withColorName:(NSString*)color withMusicName:(NSString *)musicName
with:(CGRect)photoSize{
创建输出路径
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *outputURL =
[documentsDirectory stringByAppendingPathComponent:
[NSString stringWithFormat:@"FinalVideo-%d.m4v",arc4random() % 1000]];
创建导出对象
self.exportSession = [[AVAssetExportSession alloc] initWithAsset:self.mutableComposition presetName:AVAssetExportPresetHighestQuality];
视频组合器
self.exportSession.videoComposition = self.mutableVideoC
音频组合器
self.exportSession.audioMix = self.mutableAudioM
self.exportSession.shouldOptimizeForNetworkUse = YES;
self.exportSession.outputURL = [NSURL fileURLWithPath:outputURL];
self.exportSession.outputFileType = AVFileTypeQuickTimeM
[self.exportSession exportAsynchronouslyWithCompletionHandler:^(void){
switch (self.exportSession.status) {
case AVAssetExportSessionStatusCompleted:{
dispatch_async(dispatch_get_main_queue(), ^{
//输出完成后
[self writeVideoToPhotoLibrary:self.exportSession.outputURL];
发送通知到指定的界面
[[NSNotificationCenter defaultCenter] postNotificationName:AVSEExportCommandCompletionNotification
object:self];
case AVAssetExportSessionStatusFailed:
NSLog(@"Failed:%@",self.exportSession.error);
[[NSNotificationCenter defaultCenter] postNotificationName:@"ExportCommandFaild" object:nil];
case AVAssetExportSessionStatusCancelled:
NSLog(@"Canceled:%@",self.exportSession.error);
- (void)writeVideoToPhotoLibrary:(NSURL *)url
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
保存视频到指定的相溥
[library saveVideo:url toAlbum:PHOTO_ALBUM_NAME completion:^(NSURL *assetURL, NSError *error) {
} failure:^(NSError *error) {
原文链接http://www.cnblogs.com/kenshincui/p/4186022.html 音频在iOS中音频播放从形式上可以分为音效播放和音乐播放。前者主要指的是一些短音频播放,通常作为点缀音频,对于这类音频不需要进行进度、循环等控制。后者指的是一些较长的音...
先说视频合并 这是视频和音频合并 因为使用shareAEC sdk录屏unity画面 面对物体时候和easyARyou冲突 会黑屏 最终使用unity官方推荐的everyPlayer录屏 但是录不到unity自带的声音为,所以在录屏的时候进行录音,下面是录音的关键代码 -(...
最终诉求? 拍摄、保存、播放、上传。就这四个步骤,当然首先拍摄就有许许多多的优化小功能,切换摄像头、单击跳帧焦距、双击远近距离切换、上移取消拍摄。 保存功能就只有一个保存到本地沙盒的功能。 播放自然就涉及到原生或是三方库来播放的问题,用什么第三方库来播放。 上传就有几种情况...
iOS开发系列--网络开发 概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博、微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的。如今,网络编程越来越普遍,孤立的应用通常是没有生命力的。今天就会给大家介绍这部分内容: 目录 1....
1、改变 UITextField 占位文字 颜色和去掉底部白框 [_userName setValue:[UIColor whiteColor] forKeyPath:@&_placeholderLabel.textColor&]; //去掉底部白框[UIView setA...
寒玉痴痴的望着对自己不问不见的涤尘,想起往昔的一幕一幕,心中痛的无法言语,贝齿几欲咬破下唇。 “就那么一晚,你便连看我一眼也不愿意了么?” 寒玉只感觉自己的心在滴血,那往日的甜蜜,此刻都化作无数的利刃将自己的心划做一片一片,疼得厉害。 哪怕是你真的做了,只要你的心中真的是有...
手把手系类-利用第三方平台免费 在写这篇文章前,我曾经在学校运营过两个微信公众号,一个是服务号,一个是订阅号,服务号是用来做校园服务市场的,订阅号就是发发一些无聊的东西之类的吧,不过没有坚持多长时间就因为这样那样的事没有坚持了,这就是为什么很多人说——做一件事容易,坚持做一...
1 我刚工作的第二年认识了静。 那是夏天,长发披肩的静喜欢长裙。静又瘦,夏日的风里,裙裾飘飘颇有几分仙气。 那时我们的小团队有五六个人,经常聚在一起玩,无非是逛街吃饭没完没了的闲扯。而静是话最少的那个。 有一天他们其他人都各有各的事情,只有我和静闲极无聊跑街上去瞎逛,悠哉悠...
鄙人跳old school风格街舞;玩街头滑板、bmx;尬面包甜品;看文学小说;试图了解学习精酿啤酒知识...我是一个喜欢玩的人,但是我不愿意去和别人说这个怎么玩怎么做,要么你就来找我一起玩。学习兴趣的过程就是一个就医的过程,别人需要望闻问切才能给你对症下药,你的兴趣才能...
文件共享服务介绍 文件共享服务,就是在云上提供共享文件系统,让多台云主机非常方便地共享文件,最参见的共享文件系统包括NFS和CIFS。 为了实现文件共享服务,我们基于OpenStack Manila顶级项目提供了NFS和CIFS文件共享的支持。 Manila项目介绍 Man...iOS视频添加水印遇到的坑 - 简书
iOS视频添加水印遇到的坑
在做iOS视频相关的开发的时候,遇到了一点点坑。iOS视频添加水印,你首先会想到使用
, 苹果官方是这样写的A video composition describes, for any time in the aggregate time range of its instructions, the number and IDs of video tracks that are to be used in order to produce a composed video frame corresponding to that time. When AV Foundation’s built-in video compositor is used, the instructions an AVVideoComposition comprises can specify a spatial transformation, an opacity value, and a cropping rectangle for each video source, and these can vary over time via simple linear ramping functions.然后就按照步骤实现就可以了
// 1 - set up the overlay
CALayer *overlayLayer = [CALayer layer];
[overlayLayer setContents:(id)[image CGImage]];
overlayLayer.frame = CGRectMake(0, 0, size.width, size.height);
[overlayLayer setMasksToBounds:YES];
// 2 - set up the parent layer
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, size.width, size.height);
videoLayer.frame = CGRectMake(0, 0, size.width, size.height);
[parentLayer addSublayer:videoLayer];
[parentLayer addSublayer:overlayLayer];
// 3 - apply magic
composition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer
但是在iOS 10下发现,有时候这个方法导出的视频不能立即播放,要等一会儿视频才能播放,于是就使用了下面的这个接口
CIFilter *watermarkFilter = [CIFilter filterWithName:@"CISourceOverCompositing"];
mainVideoComposition= [AVMutableVideoComposition videoCompositionWithAsset:mixComposition applyingCIFiltersWithHandler:^(AVAsynchronousCIImageFilteringRequest * _Nonnull request) {
CIImage *watermarkImage
[[CIImage alloc] initWithCGImage:image.CGImage];
CIImage *source = request.sourceI
[watermarkFilter setValue:source forKey:kCIInputBackgroundImageKey];
[watermarkFilter setValue:[watermarkImage imageByApplyingTransform:CGAffineTransformMakeScale(source.extent.size.width/watermarkImage.extent.size.width, source.extent.size.height/watermarkImage.extent.size.height)] forKey:kCIInputImageKey];
[request finishWithImage:watermarkFilter.outputImage context:nil];
Why Stock Markets CrashThis page intentionally left blankWhy Stock Markets CrashCritical Events in ComplexFinancial SystemsD i d i e r S ...
自己到现在毕业一年,总结了自己在前段时间开发当中遇到的的一些细节问题,水平有限,希望有可以帮助大家的 1,在OC中使用 “%s,__func__”打印出类名和方法例如: NSlog(@“%s”,__func__); 打印出 -[Person dealloc] 2,RunLo...
教程一:视频截图(Tutorial 01: Making Screencaps) 首先我们需要了解视频文件的一些基本概念,视频文件本身被称作容器,例如avi或者是quicktime,容器的类型确定 了文件的信息。然后,容器里装的东西叫流(stream),通常包括视频流和音频...
在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建基础动画、关键帧动画、动画组、转场动画,如何通过UIView的装饰方法对这些动画操作进行简化等。在今...
视频处理主要是用到以下这几个类 AVMutableComposition、AVMutableVideoComposition、AVMutableAudioMix、AVMutableVideoCompositionInstruction、AVMutableVideoCompo...
最近这几天有点浮躁,可能是因为法制培训班的缘故吧,有时候要去听课,有时候要去串门,导致每日用于备战比武的时间大幅减少,实在惭愧。 摸索了这么一个周的时间了,还是没有找到一种行之有效的复习方法。这次比武类似司考又不是司考,没有录音可听,只有大量的书和题。先看法条再做题应该是个...
https://www.mesta-automation.com/modbus-with-c-sharp-libraries-examples/#prettyPhoto
昨天凌晨5点爬起来,翻完了《LIFECYCLING》的最后一个章节,Samiro Yunoki对于民间艺术的修养感悟,再也睡不着就起来码文,曾经写过的稿子拿出来从头到尾的改了个遍,Public第一篇的推送,branding sth. new. 如果你有在看到“pop”,会让...
基本信息 时间: 05:00-07:08 下次安排:继续 行为与注意力的分析阅读 公告、信息及资源链接:http://fastslow.top 背景:永澄老大在机场,没设备,一起按照自己的进度阅读。永澄分享,并对饭饭的导图做了指导——结构化。 这结构化是...
左手仓央嘉措,右手纳兰容若。 仓央嘉措与纳兰性德,一个是认定的转世灵童,却寻觅着不负如来不负卿的双全之法;一个是注定的庙堂权臣,却常有远离高门广厦,心系山泽鱼鸟之思。两个难逃命运的人,怀揣着同一种淡泊离世的深情。在一生的寻觅与伤怀中,留给我们一篇篇绝世情话。 仓央嘉措说: ...

我要回帖

更多关于 ios去水印的app 的文章

 

随机推荐