возникли проблемы с созданием эффекта Кена Бернса с помощью CALayer для iphone - PullRequest
3 голосов
/ 25 февраля 2012

Последние несколько дней я пытался создать эффект прожига кена, используя 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];

Проблема, с которой я столкнулся, заключается в том, что конечный результат панорамирования и масштабирования отключается на несколько пикселей на экране.

Если кто-то знает, как это исправить, я был бы очень признателен.

1 Ответ

0 голосов
/ 30 июля 2012

Все преобразования применяются относительно точки привязки.Попробуйте использовать опорную точку

CGPoint anchor = CGPointMake(0.5f, 0.5f);

Ваш «видовой экран» больше не должен масштабироваться внизу справа (если это связано с отключением анимации на несколько пикселей), но одинаково во всех направлениях.

...