gpt4 book ai didi

ios - 带有 CALayers 的 CAAnimation 偶尔会创建闪烁的动画(包括视频)

转载 作者:行者123 更新时间:2023-12-01 16:50:25 25 4
gpt4 key购买 nike

我的应用程序会拍摄一张静态照片并为嘴部区域设置动画以模拟说话。然而,大约有 1/4 的时间,一些隐藏的 calayer 会在整个动画中不断闪烁。

这是应用程序在 works properly 时的样子.
这是应用程序在 glitches 时的样子.
编辑:一个 better video

我假设问题与路径有关。在应用程序中,用户围绕嘴部区域创建一条路径(视频中简要显示),这将是动画区域。有时路径会产生平滑的动画,有时会导致上述故障。此外,如果我按下“返回”并尝试用动画重新加载 Controller ,故障仍然存在,而如果我在重新加载之前更改路径,它偶尔会消失。

如果它与路径无关,那么我消除的一些罪魁祸首是:

  • 图像类型/来源——有时它适用于图像 a 但不适用于图像
    b,其他时候它适用于图像 b,但不适用于 a。我试过了
    照片库中的图像以及从互联网上保存的图像。
  • iphone vs 模拟器——两个设备都出现问题
  • 动画图片的数量 - 有时它会在第一张发生
    尝试;其他时候它会在第 5 次或第 6 次尝试时发生。

  • 下面是动画 View 中的代码。我首先创建一个全黑的图层,然后是图片减去嘴巴区域的图层,最后是仅嘴巴区域的图层。然后我移动嘴层的位置,使位移变成黑色,看起来像张开的嘴巴。

    编辑:另外,如果我通过从面层移除蒙版来移除嘴孔,动画运行顺利。
    - (id)initWithFrame:(CGRect)frame leftPt:(CGPoint)point0 rightPt:(CGPoint)point2 vertex1:(CGPoint)vertex1 vertex2:(CGPoint)vertex2 andPicture:(UIImage *)pic{

    self = [super initWithFrame:frame];
    if (self) {

    p0 = point0;
    p2 = point2;
    v1 = vertex1;
    v2 = vertex2;
    picture = pic;

    [self addBlackLayer];
    [self addFaceLayer];
    [self addMouthLayer];

    self.opaque = YES;
    }
    return self;
    }
    - (void)addBlackLayer {

    CALayer *blackLayer = [CALayer layer];
    blackLayer.frame = self.bounds;
    blackLayer.backgroundColor = [UIColor blackColor].CGColor;
    [self.layer addSublayer:blackLayer];

    }
    - (void)addFaceLayer {

    CALayer *faceLayer = [CALayer layer];
    faceLayer.frame = self.bounds;
    faceLayer.contents = (id)[picture CGImageWithProperOrientation];
    CAShapeLayer *faceMask = [CAShapeLayer layer];
    CGMutablePathRef fPath = CGPathCreateMutable();
    CGPathMoveToPoint(fPath, NULL, CGRectGetMinX(self.bounds), CGRectGetMinY(self.bounds));
    CGPathAddLineToPoint(fPath, NULL, CGRectGetMaxX(self.bounds), CGRectGetMinY(self.bounds));
    CGPathAddLineToPoint(fPath, NULL, CGRectGetMaxX(self.bounds), CGRectGetMaxY(self.bounds));
    CGPathAddLineToPoint(fPath, NULL, CGRectGetMinX(self.bounds), CGRectGetMaxY(self.bounds));
    CGPathAddLineToPoint(fPath, NULL, CGRectGetMinX(self.bounds), CGRectGetMinY(self.bounds));
    CGPathMoveToPoint(fPath, NULL, p0.x, p0.y);
    midpt = CGPointMake( (p2.x + p0.x)/2, (p2.y+ p0.y)/2);
    CGPoint c1 = CGPointMake(2*v1.x - midpt.x, 2*v1.y - midpt.y); //control points
    CGPoint c2 = CGPointMake(2*v2.x - midpt.x, 2*v2.y - midpt.y);

    CGPathAddQuadCurveToPoint(fPath, NULL, c1.x, c1.y, p2.x, p2.y);
    CGPathAddQuadCurveToPoint(fPath, NULL, c2.x, c2.y, p0.x, p0.y);

    faceMask.path = fPath;
    faceLayer.mask = faceMask;
    [faceMask setFillRule:kCAFillRuleEvenOdd];
    [self.layer addSublayer:faceLayer];
    CGPathRelease(fPath);

    }

    - (void)addMouthLayer {

    CGMutablePathRef mPath = CGPathCreateMutable();
    CGPathMoveToPoint(mPath, NULL, p0.x, p0.y);
    midpt = CGPointMake( (p2.x + p0.x)/2, (p2.y+ p0.y)/2);
    CGPoint c1 = CGPointMake(2*v1.x - midpt.x, 2*v1.y - midpt.y); //control points
    CGPoint c2 = CGPointMake(2*v2.x - midpt.x, 2*v2.y - midpt.y);

    CGPathAddQuadCurveToPoint(mPath, NULL, c1.x, c1.y, p2.x, p2.y);
    CGPathAddQuadCurveToPoint(mPath, NULL, c2.x, c2.y, p0.x, p0.y);

    self.mouthLayer = [CALayer layer];
    CAShapeLayer *mouthMask = [CAShapeLayer layer];
    self.mouthLayer.frame = self.bounds;
    self.mouthLayer.contents = (id)[picture CGImageWithProperOrientation];
    mouthMask.path = mPath;
    mouthMask.frame = mouthLayer.bounds;
    self.mouthLayer.mask = mouthMask;
    [self.layer addSublayer:mouthLayer];
    self.mouthLayer.frame = CGRectMake(mouthLayer.frame.origin.x, mouthLayer.frame.origin.y, mouthLayer.frame.size.width, mouthLayer.frame.size.height);
    CGPathRelease(mPath);

    这是从 View Controller 创建动画的代码
    - (CAAnimation *)createAnimationWithRepeatCount:(int)count {

    CGPoint convertedStartingCenter = [self.view convertPoint:animatedFace.center toView:animatedFace];
    CGPoint endPt = CGPointMake(convertedStartingCenter.x, convertedStartingCenter.y + 15);

    CABasicAnimation *mouthDown = [CABasicAnimation animationWithKeyPath:@"position"];
    mouthDown.duration = ANIMATION_TIME;
    mouthDown.beginTime = 0;
    mouthDown.fromValue = [NSValue valueWithCGPoint:convertedStartingCenter];
    mouthDown.toValue = [NSValue valueWithCGPoint:endPt];

    CABasicAnimation *mouthUp = [CABasicAnimation animationWithKeyPath:@"position"];
    mouthUp.duration = ANIMATION_TIME;
    mouthUp.beginTime = ANIMATION_TIME;
    mouthUp.fromValue = [NSValue valueWithCGPoint:endPt];
    mouthUp.toValue = [NSValue valueWithCGPoint:convertedStartingCenter];

    CAAnimationGroup *totalAnimation = [CAAnimationGroup animation];
    [totalAnimation setAnimations:[NSArray arrayWithObjects:mouthDown,mouthUp, nil]];
    [totalAnimation setDuration:2*ANIMATION_TIME];
    [totalAnimation setRemovedOnCompletion:NO];
    [totalAnimation setFillMode:kCAFillModeForwards];
    totalAnimation.repeatCount = count;

    return totalAnimation;

    }

    最佳答案

    只是另一种方法(不知道您是否尝试过),您只能使用 CABasicAnimation并将您的类设置为动画委托(delegate),在委托(delegate)方法中您可以尝试启动下一个 CABasicAnimation .如果您没有尝试过,我可以为您提供一个示例。

    关于ios - 带有 CALayers 的 CAAnimation 偶尔会创建闪烁的动画(包括视频),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16556824/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com