【问题标题】:methods sequence by NSMutableArray/NSMutableDictionary contents (Image multi-effecting)按 NSMutableArray/NSMutableDictionary 内容排序的方法(图像多重效果)
【发布时间】:2012-11-05 13:31:20
【问题描述】:

我想做什么:

我想实现用户在图像上使用 CIFilters 的能力。所以我需要以某种方式修复它的顺序。例如,如果用户打开图像,然后应用CIGaussianBlur,然后是CIColorControls,然后是CISepia,我需要得到这样的结果:

On user opened image apply CIGaussianBlur -> on CIGaussianBlur output image apply CIColorControls - > on CIColorControls output image apply CISepia.

没关系。但是如果用户关闭 CIGaussianBlur 怎么办?然后我需要重复这个效果的序列,而不会模糊。它看起来像这样:

On user opened image apply CIColorControls -> on CIColorControls output image apply CISepia.

问题

是否可以这样做:

应用任何效果后,在 NSMutableArray 或 NSMutableDictionary 中添加一些字符串。然后在应用其他效果时,检查 NSMutableArray 或 NSMutableDictionary 内容,如下所示:

如果索引 0 处的对象等于“模糊”,则在源图像上应用模糊,然后像当前效果的输入图像一样获取模糊的输出图像

等等?因此,每次都会按照用户制作的顺序重新应用效果。

如果可能的话,也许有人可以建议我任何解决方案?

【问题讨论】:

  • 效果应该可以应用多次吗?如果是这样,那么 NSMutableArray 是显而易见的选择。
  • 好吧,它们只能应用一次,但用户总是可以随时调整它的参数。如果用户这样做:CIColorControls->CIGaussianBlur->CISepia->CISaturation 他可以获得灰度图像,如果他这样做:CIColorControls->CIGaussianBlur->CISaturation->CISepia 也许他可以获得棕褐色图像?这取决于编码时将使用的逻辑巫婆。但这没什么大不了的。两种变体都适合我。
  • 如果我选择 NSMutableArray,有没有办法检查它的内容并根据添加方法的顺序,而不是在 while 循环中写很多 if's

标签: objective-c image macos effects core-image


【解决方案1】:

我认为这是使用factory 想法的一个很好的例子。

您应该存储过滤器数组以将图像处理为数组 - 保持排序顺序,并且处理起来相当简单(除了 NSCountedSet 之类的东西)。

接下来要问的合乎逻辑的问题是,我们如何在这里应用工厂模式?要考虑的最重要的事情是上下文对象应该是什么类型?以下是一些想法:

  1. 使用NSString 作为常量标识符。
    • 可能是最简单的开始,它的 ,并且易于理解 - 缺点是它比其他选项慢,并且可能会变得非常复杂 if-else 块,因为您不能在 a 上使用 switch 语句NSString

  2. NSNumber,包装一个枚举值。

    • 这可能是更好的选择之一。您可以直接转换为 int 变量,它在我能想象到的几乎任何处理器上都相当快,而且,如果您使用 ObjC 2.5 的花哨文字,您可以这样做:

      [filters addObject:@(filterType_gaussianBlur)];
      

      其中filterType_gaussianBlur 是一个枚举常量或其他东西。

      使用enum 的另一个优点是支持开箱即用的switch 语句。如果处理得当,它会清理您的代码,它比大型 if-else 块更快,唯一需要注意的是确保您正确地 break

  3. 存储 Class 对象

    • 这可能需要一些解释。在objective-c中,实际上可以存储对对象类型的引用,CIGaussianBlurNSStringNSData等。

      此类“对象”允许您仅根据对象的类型动态创建对象,例如:

      Class cls = nil;
      
      if (stringMutable)
          cls = [NSMutableString class];
      else
          cls = [NSString class];
      
      NSString *mutableOrNot = [[cls alloc] initWithString:@"Hello World!"];
      

      但是,这种方法的缺点是无法在初始化后配置对象,并且您必须使用相同的选择器(方法)来初始化每个对象。如果这不是问题(我不使用 CoreImage),那么使用 Class 方法应该没问题。

总而言之,在这种情况下使用任何有意义的东西。如果这些过滤器在初始化后不需要额外的配置,那么方法 3 很有意义。我个人不建议使用 1 方法,除非确实需要使用字符串。 只要有可能,请始终尝试控制对象可以具有的值。这会让你的生活变得更轻松,相信我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多