我制作的应用程序添加了"贴纸"到在背景视图中播放的视频。贴纸作为imageView添加,响应平移,捏合和旋转手势,缩放和旋转然后应用于UIImageview作为变换
要将ImageView添加到视频中,我必须将它们渲染为CALayer,如下面的代码
- (void)applyVideoEffectsToComposition:(AVMutableVideoComposition *)composition size:(CGSize)videoSize {
CGSize screenSize = self.view.frame.size;
CGFloat scale = videoSize.width / screenSize.width; //get scale between video recorded and the screen used to edit
//Creates parentLayer that contains videoLayer and each image layer
for (UIImageView *imageView in [self.stickerContainer subviews]) {
CALayer *layer = [CALayer layer];
[layer setContents:(id)[imageView.image CGImage]];
//Set layer frame
CGRect imageFrame = imageView.frame;
CGRect imageBounds = imageView.bounds;
CGRect frame = CGRectMake(imageFrame.origin.x * scale, imageFrame.origin.y * scale, imageBounds.size.width * scale, imageBounds.size.height * scale);
layer.frame = frame;
//Second set transform
CGAffineTransform transform = imageView.transform;
layer.transform = CATransform3DMakeAffineTransform(transform);
[layer setMasksToBounds:YES];
[parentLayer addSublayer:layer];
}
composition.animationTool = [AVVideoCompositionCoreAnimationTool
videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
}
基本上创建一个具有与imageView相同的框架和转换的图层。但这会使每个手势产生奇怪的结果
无论如何..对于为什么会发生这种情况的任何想法?..如果我的图像没有任何变换并且完全居中,它看起来应该如此。
我的代码基于以下tutorial,因此生成新视频的代码基本相同
答案 0 :(得分:4)
所以我终于找到了一些“hacky”解决方案..我将保留代码并解释它
- (void)applyVideoEffectsToComposition:(AVMutableVideoComposition *)composition videoSize:(CGSize)videoSize screenSize:(CGSize)screenSize stickersArray:(NSArray<UIImageView *>*)stickers{
CGFloat videoScale = videoSize.width / screenSize.width; //get scale between video recorded and the screen used to edit
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
videoLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
//Add video layer first and then stickers
[parentLayer addSublayer:videoLayer];
for (UIImageView *imageView in stickers) {
CALayer *layer = [CALayer layer];
[layer setContents:(id)[imageView.image CGImage]];
//First set image size with bounds of original image and center (not affected by transform)
CGSize imageSize = imageView.bounds.size;
CGPoint center = imageView.center;
//Fix offset issue by getting bottom point of imageView to a screen size proportion
CGFloat yOffset = (center.y + imageSize.height/2) / screenSize.height;
yOffset = 1 - yOffset; // invert screen proportion
CGFloat scaledOriginX = (center.x - imageSize.width/2)* videoScale;
CGRect frame = CGRectMake(scaledOriginX, videoSize.height * yOffset, imageSize.width * videoScale , imageSize.height * videoScale);
layer.frame = frame;
//Apply transforms but to original imageView
CGAffineTransform transform = imageView.transform;
//Invert original transform b value with c value
layer.transform = CATransform3DMakeAffineTransform(CGAffineTransformMake(transform.a, transform.c, transform.b, transform.d, 0, 0));
[layer setMasksToBounds:YES];
[parentLayer addSublayer:layer];
}
composition.animationTool = [AVVideoCompositionCoreAnimationTool
videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
}
最初我的代码存在缺陷,因为我使用的是imageView.frame
(size
和origin
),它们都受到变换矩阵的影响,因此为{{1}提供了一个奇怪的帧}}。相反,我应该使用imageView CALayer
和bounds
,不受变换矩阵影响或改变,因为this answer显示
这可以修复缩放和原点问题,但是平移和旋转问题仍然存在
要修复平移手势问题,我必须手动“反转”y轴,因为这部分代码显示
center
要修复反向旋转,我必须手动反转变换b和c值
//Fix offset issue by getting bottom point of imageView to a screen size propotion
CGFloat yOffset = (center.y + imageSize.height/2) / screenSize.height;
yOffset = 1 - yOffset;
CGFloat scaledOriginX = (center.x - imageSize.width/2)* videoScale;
CGRect frame = CGRectMake(scaledOriginX, videoSize.height * yOffset, imageSize.width * videoScale , imageSize.height * videoScale);
layer.frame = frame;
基本上就是这个......不知道为什么会发生旋转和平移问题,但这应该解决它。我真的希望有人能有比我更好的解决方案,并且知道为什么会出现这两个问题。