【问题标题】:Does iOS 5 support blur CoreImage fiters?iOS 5 是否支持模糊核心图像滤镜?
【发布时间】:2012-01-21 15:48:30
【问题描述】:

根据文档,它应该支持模糊,请注意“在 iOS 5.0 及更高版本中可用”:

CIFilter Class Reference

但根据设备,它没有:

[CIFilter filterNamesInCategory:kCICategoryBlur];

什么都不返回。

根据以下内容,我的 iPhone 和模拟器(均运行 5.0)上只有这些过滤器可用:

[CIFilter filterNamesInCategory:kCICategoryBuiltIn]

CIAdditionCompositing,
CIAffineTransform,
CICheckerboardGenerator,
CIColorBlendMode,
CIColorBurnBlendMode,
CIColorControls,
CIColorCube,
CIColorDodgeBlendMode,
CIColorInvert,
CIColorMatrix,
CIColorMonochrome,
CIConstantColorGenerator,
CICrop,
CIDarkenBlendMode,
CIDifferenceBlendMode,
CIExclusionBlendMode,
CIExposureAdjust,
CIFalseColor,
CIGammaAdjust,
CIGaussianGradient,
CIHardLightBlendMode,
CIHighlightShadowAdjust,
CIHueAdjust,
CIHueBlendMode,
CILightenBlendMode,
CILinearGradient,
CILuminosityBlendMode,
CIMaximumCompositing,
CIMinimumCompositing,
CIMultiplyBlendMode,
CIMultiplyCompositing,
CIOverlayBlendMode,
CIRadialGradient,
CISaturationBlendMode,
CIScreenBlendMode,
CISepiaTone,
CISoftLightBlendMode,
CISourceAtopCompositing,
CISourceInCompositing,
CISourceOutCompositing,
CISourceOverCompositing,
CIStraightenFilter,
CIStripesGenerator,
CITemperatureAndTint,
CIToneCurve,
CIVibrance,
CIVignette,
CIWhitePointAdjust

【问题讨论】:

  • 文档说kCICategoryBlur 常量是可用的,它就是。您在[CIFilter filterNamesInCategory:kCICategoryBlur]; 中成功使用了它。这告诉您当时没有可用的模糊滤镜。
  • @idz 这让我笑了,谢谢!

标签: cocoa-touch ios5 core-image


【解决方案1】:

不幸的是,它不支持任何模糊。为此,您必须自己动手。

【讨论】:

    【解决方案2】:

    我也很失望地发现 iOS 中的 Core Image 不支持模糊。这是我编写的用于在 UIImage 上进行 9 抽头高斯模糊的函数。反复调用以获得更强的模糊效果。

    @interface UIImage (ImageBlur)
    - (UIImage *)imageWithGaussianBlur9;
    @end
    
    @implementation UIImage (ImageBlur)
    - (UIImage *)imageWithGaussianBlur9 {
        float weight[5] = {0.2270270270, 0.1945945946, 0.1216216216, 0.0540540541, 0.0162162162};
        // Blur horizontally
        UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
        [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[0]];
        for (int x = 1; x < 5; ++x) {
            [self drawInRect:CGRectMake(x, 0, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[x]];
            [self drawInRect:CGRectMake(-x, 0, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[x]];
        }
        UIImage *horizBlurredImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        // Blur vertically
        UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
        [horizBlurredImage drawInRect:CGRectMake(0, 0, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[0]];
        for (int y = 1; y < 5; ++y) {
            [horizBlurredImage drawInRect:CGRectMake(0, y, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[y]];
            [horizBlurredImage drawInRect:CGRectMake(0, -y, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[y]];
        }
        UIImage *blurredImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        //
        return blurredImage;
    }
    

    只需像这样在现有图像上调用它:

    UIImage *blurredImage = [originalImage imageWithGaussianBlur9];
    

    并重复它以获得更强的模糊效果,如下所示:

    blurredImage = [blurredImage imageWithGaussianBlur9];
    

    【讨论】:

    • 出色的低依赖解决方案
    【解决方案3】:

    再次,为了挽救所有 iOS 模糊问题,这是我的贡献:

    https://github.com/tomsoft1/StackBluriOS

    一个基于 Stack Blur 的简单模糊库。 Stack Blur 与 Gaussian Blur 非常相似,但速度更快(参见http://incubator.quasimondo.com/processing/fast_blur_deluxe.php

    像这样使用它:

    UIImage *newIma=[sourceIma stackBlur:radius]
    

    希望有帮助

    【讨论】:

    • 我已经实现了自己的应用,并且该应用已经在应用商店上架,但我会记住这一点以供将来参考。感谢您的提示!
    • StackBlur iOS 将图像旋转 90 度。我认为它应该修复
    • @ppaulojr 你确定轮换问题吗?它应该保持所有其他参数相同。如果仍有问题,请提供测试代码有问题的示例图片
    • iOS 6.0 :- m_PixelBuf[offset]=dv[rsum]; 提供 EXC_BAD_ACCESS(code=2, addres=******`
    • 图书馆似乎有一些奇怪的大小问题
    【解决方案4】:

    虽然 iOS 5.0 上的 Core Image 缺少模糊过滤器,但仍有一种方法可以获得 GPU 加速的图像和视频模糊效果。我的开源GPUImage 框架有多种模糊类型,包括 Gaussian(使用 GPUImageGaussianBlurFilter 用于一般 Gaussian 或 GPUImageFastBlurFilter 用于硬件优化的 9-hit Gaussian)、box(使用 GPUImageBoxBlurFilter)、median(使用 GPUImageMedianFilter)、和双边模糊(使用 GPUImageBilateralBlurFilter)。

    我在this answer 中描述了用于实现硬件优化的高斯模糊的着色器,您可以检查我在框架内用于其余部分的代码。这些过滤器的运行速度比我尝试过的任何 CPU 密集型例程快数十倍。

    我还将这些模糊融入到多阶段处理效果中,例如不锐化遮罩、倾斜移位过滤、Canny 边缘检测和 Harris 角点检测,所有这些都可以作为该框架内的过滤器使用。

    【讨论】:

    • 布拉德,你太棒了,图书馆真是太棒了!很遗憾我不能多次投票。
    【解决方案5】:

    这里是我们教程的链接,使用不同的方法在 iOS 应用程序中制作模糊效果。 http://blog.denivip.ru/index.php/2013/01/blur-effect-in-ios-applications/?lang=en

    【讨论】:

      【解决方案6】:

      更新:从 iOS 6 开始,[CIFilter filterNamesInCategory:kCICategoryBlur]; 返回CIGaussianBlur,这意味着该过滤器在设备上可用。尽管这是真的,但您(可能)会使用 GPUImage 获得更好的性能和更大的灵活性。

      【讨论】:

      • 我发现 CIFilter blur 非常不稳定。有时,它会在我的 iPad 上导致非常奇怪的崩溃,锁定屏幕,但我可以告诉 iPad 仍然可以正常工作,因为当它响应触摸时我可以听到声音。我必须硬重置才能修复它。无论如何,上面 John Stephan 的替换是一个很好的解决方案。
      【解决方案7】:

      如果您可以在您的 iOS 应用程序中使用 OpenGL ES,您可以通过以下方式计算所选像素邻域半径中的中值(当然,中值是一种模糊):

      kernel vec4 medianUnsharpKernel(sampler u) {
      vec4 pixel = unpremultiply(sample(u, samplerCoord(u)));
      vec2 xy = destCoord();
      int radius = 3;
      int bounds = (radius - 1) / 2;
      vec4 sum  = vec4(0.0);
      for (int i = (0 - bounds); i <= bounds; i++)
      {
          for (int j = (0 - bounds); j <= bounds; j++ )
          {
              sum += unpremultiply(sample(u, samplerTransform(u, vec2(xy + vec2(i, j)))));
          }
      }
      vec4 mean = vec4(sum / vec4(pow(float(radius), 2.0)));
      float mean_avg = float(mean);
      float comp_avg = 0.0;
      vec4 comp  = vec4(0.0);
      vec4 median  = mean;
      for (int i = (0 - bounds); i <= bounds; i++)
      {
          for (int j = (0 - bounds); j <= bounds; j++ )
          {
              comp = unpremultiply(sample(u, samplerTransform(u, vec2(xy + vec2(i, j)))));
              comp_avg = float(comp);
              median = (comp_avg < mean_avg) ? max(median, comp) : median;
          }
      }
      
      return premultiply(vec4(vec3(abs(pixel.rgb - median.rgb)), 1.0)); 
      }
      

      步骤的简要说明 1. 计算 3x3 邻域中源像素周围像素值的平均值; 2. 找出同一邻域中小于均值的所有像素的最大像素值。 3. [可选] 从源像素值中减去中间像素值进行边缘检测。

      如果您使用中值进行边缘检测,有几种方法可以修改上述代码以获得更好的结果,即混合中值过滤和截断媒体过滤(替代和更好的“模式”过滤) .如果您有兴趣,请询问。

      【讨论】:

        【解决方案8】:

        因为我使用的是 Xamarin,所以我将 John Stephen 的答案转换为 C#:

            private UIImage ImageWithGaussianBlur9(UIImage image)
            {
                var weight = new nfloat[]
                {
                    0.2270270270f, 0.1945945946f, 0.1216216216f, 0.0540540541f, 0.0162162162f
                };
        
                var width = image.Size.Width;
                var height = image.Size.Height;
                // Blur horizontally
                UIGraphics.BeginImageContextWithOptions(image.Size, false, 1f);
        
                image.Draw(new CGRect(0f, 0f, width, height), CGBlendMode.PlusLighter, weight[0]);
        
                for (int x = 1; x < 5; ++x)
                {
                    image.Draw(new CGRect(x, 0, width, height), CGBlendMode.PlusLighter, weight[x]);
                    image.Draw(new CGRect(-x, 0, width, height), CGBlendMode.PlusLighter, weight[x]);
                }
        
                var horizBlurredImage = UIGraphics.GetImageFromCurrentImageContext();
                UIGraphics.EndImageContext();
        
                // Blur vertically
                UIGraphics.BeginImageContextWithOptions(image.Size, false, 1f);
        
                horizBlurredImage.Draw(new CGRect(0, 0, width, height), CGBlendMode.PlusLighter, weight[0]);
        
                for (int y = 1; y < 5; ++y)
                {
                    horizBlurredImage.Draw(new CGRect(0, y, width, height), CGBlendMode.PlusLighter, weight[y]);
                    horizBlurredImage.Draw(new CGRect(0, -y, width, height), CGBlendMode.PlusLighter, weight[y]);
                }
        
                var blurredImage = UIGraphics.GetImageFromCurrentImageContext();
                UIGraphics.EndImageContext();
        
                return blurredImage;
            }
        

        【讨论】:

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