【问题标题】:Most performant way to change a uiimage saturation (during animation)更改 uiimage 饱和度的最高效方法(在动画期间)
【发布时间】:2014-12-10 19:14:17
【问题描述】:

我正在尝试在动画期间更改 UIImage 饱和度。但这样做似乎太重/太慢了:

-(void) changeSaturation:(CGFloat)value{

CIContext * context = [CIContext contextWithOptions:nil];

CIFilter *colorControlsFilter = [CIFilter filterWithName:@"CIColorControls"];

 CIImage *image = self.imageView.image.CIImage;

[colorControlsFilter setValue:image forKey:@"inputImage"];

[colorControlsFilter setValue:[NSNumber numberWithFloat:value] forKey:@"inputSaturation"];

CIImage *outputImage = [colorControlsFilter outputImage];

CGImageRef cgimg = [context createCGImage:outputImage
                                 fromRect:[outputImage extent]];

UIImage *newImage = [UIImage imageWithCGImage:cgimg];
self.imageView.image = newImage;

CGImageRelease(cgimg);}

每次用户拖动视图时都会调用此方法(当距离改变时,饱和度也会改变),这显然不是正确的方法,但我想要类似的行为。 我想知道我是否可以通过 UIImageview 顶部的图层来实现这一点。

谁能告诉我如何实现我的目标?

【问题讨论】:

  • 您的问题动画或滞后?
  • 动画中途中断
  • 需要平滑更改图像吗?
  • 我想问题应该与图像更改或创建有关。不确定

标签: ios uiimageview uiimage hsv ciimage


【解决方案1】:

1) async 方法计算过滤后的图像:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

        UIImage * filtredImage = /*Your method*/

        dispatch_async(dispatch_get_main_queue(), ^{
             self.imageView.image = filtredImage;
        }
}

2) 平滑变换图像:使用coreAnimation。 self.layer - 在你看来是顶级 CALayer

- (UIImage*)changeSaturation:(CGFloat)value
{
     //Your filter process
}
- (void)changeSaturation:(CGFloat)value duration:(CGFloat)duration
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

            NSUInteger cadreCount = ceil(duration * 60);
            CGFloat incrimentValue = value / cadreCount;

            NSMutableArray * mutArrayAnimationValues = [NSMutableArray new];

            for (int cadreIndex = 0; cadreIndex <= cadreCount; cadreIndex++)
            {
                  CGFloat currentValue = incrimentValue * cadreIndex;
                  UIImage * imageForCurrentCadr = [self changeSaturation:currentValue];
                  [mutArrayAnimationValues addObject:(id)imageForCurrentCadr.CGImage];
            }

            dispatch_async(dispatch_get_main_queue(), ^{

                 self.layer.contents = (id)[mutArrayAnimationValues lastObject];

                 CAKeyframeAnimation *animation = [CAKeyframeAnimation               animationWithKeyPath:@"contents"];
                 [animation setValues:mutArrayAnimationValues];
                 [animation setDuration:duration];
                 [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
                 [animation setFillMode:kCAFillModeBoth];
                 [pathAnimation setRemovedOnCompletion:NO];
                 [self.layer addAnimation:pathAnimation forKey:@"imageAnimation"];
            }
    }
}

【讨论】:

  • 在您的回答中,您指的是 - (void)changeSaturation:(CGFloat)value duration:(CGFloat)duration 中的“持续时间”。这应该是动画的持续时间吗?如果是这样,我不知道它的长度。正如我所提到的,用户正在拖动此视图,以便它可以永远持续
  • 也许,设置持续时间 0.1 秒
【解决方案2】:

原来我的主要问题是被拖动的视图包含一个大分辨率的图像。我上面的解决方案工作得很好。

【讨论】:

    【解决方案3】:

    如果您在 0.0 和 1.0 之间更改饱和度,您可以在普通图像上方添加黑白(灰度)图像并将其更改为 alpha。这将是最高效的。

    【讨论】:

      猜你喜欢
      • 2010-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-15
      • 2021-02-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-01
      相关资源
      最近更新 更多