Последние несколько дней я пытался создать эффект прожига кена, используя CALayer с анимацией, а затем сохранить его в видеофайле.
У меня есть слой с изображением, который находится внутри другого слоя с разрешением 1024x576. Все анимации применяются к слою изображения.
Вот код на данный момент:
- (CALayer*)buildKenBurnsLayerWithImage:(UIImage *)image startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint fromScale:(float)fromScale toScale:(float)toScale
{
float calFromScale = fromScale + 1;
float calToScale = toScale + 1;
float fromX = startPoint.x * calFromScale;
float fromY = (image.size.height * calFromScale) - (videoSize.height + (startPoint.y * calFromScale));
float toX = endPoint.x * calToScale;
float toY = (image.size.height * calToScale) - (videoSize.height + (endPoint.y * calToScale));
CGPoint anchor = CGPointMake(0.0, 0.0);
CALayer* imageLayer = [CALayer layer];
imageLayer.contents = (id)image.CGImage;
imageLayer.anchorPoint = anchor;
imageLayer.bounds = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
imageLayer.position = CGPointMake(image.size.width * anchor.x, image.size.height * anchor.y);
imageLayer.contentsGravity = kCAGravityResizeAspect;
// create the panning animation.
CABasicAnimation* panningAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
panningAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(-fromX, -fromY)];
panningAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-toX, -toY)];
panningAnimation.additive = YES;
panningAnimation.removedOnCompletion = NO;
// create the scale animation.
CABasicAnimation* scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
scaleAnimation.fromValue = [NSNumber numberWithFloat:fromScale];
scaleAnimation.toValue = [NSNumber numberWithFloat:toScale];
scaleAnimation.additive = YES;
scaleAnimation.removedOnCompletion = NO;
CAAnimationGroup* animationGroup = [CAAnimationGroup animation];
animationGroup.animations = [[NSMutableArray alloc] initWithObjects:panningAnimation,scaleAnimation, nil];
animationGroup.beginTime = 1e-100;
animationGroup.duration = 5.0;
animationGroup.removedOnCompletion = NO;
animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[imageLayer addAnimation:animationGroup forKey:nil];
return imageLayer;
}
Вот как я вызываю метод:
CALayer* animatedLayer = [self buildKenBurnsLayerWithImage:image startPoint:CGPointMake(100, 100) endPoint:CGPointMake(500, 500) fromScale:5.0 toScale:2.0];
Проблема, с которой я столкнулся, заключается в том, что конечный результат панорамирования и масштабирования отключается на несколько пикселей на экране.
Если кто-то знает, как это исправить, я был бы очень признателен.