【问题标题】:Using GPUImage to Recreate iOS 7 Glass Effect使用 GPUImage 重现 iOS 7 玻璃效果
【发布时间】:2014-01-20 05:08:54
【问题描述】:

我正在尝试通过将图像效果应用于MKMapView 的屏幕截图,在我的玻璃中使用 iOS 7 风格的玻璃效果。 This UIImage category,由 Apple 提供,是我用作基准的。此方法使源图像去饱和,应用淡色,并使用输入 vals 进行大量模糊:

[image applyBlurWithRadius:10.0
                 tintColor:[UIColor colorWithRed:229/255.0f green:246/255.0f blue:255/255.0f alpha:0.33] 
     saturationDeltaFactor:0.66
                 maskImage:nil];

这会产生我正在寻找的效果,但花费的时间太长——在.3.5 秒之间才能在 iPhone 4 上呈现。

我想使用出色的 GPUImage,因为我的初步尝试快了大约 5 到 10 倍,但我似乎无法做到正确。

GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:image];

GPUImageSaturationFilter *saturationFilter = [[GPUImageSaturationFilter alloc] init];
saturationFilter.saturation = 0.33; // 1.0 - 0.66;
[stillImageSource addTarget:saturationFilter];

GPUImageMonochromeFilter *monochromeFilter = [[GPUImageMonochromeFilter alloc] init];
[monochromeFilter setColor:(GPUVector4){229/255.0f, 246/255.0f, 1.0f, 0.33f}];
[monochromeFilter setIntensity:0.2];
[saturationFilter addTarget:monochromeFilter];

GPUImageFastBlurFilter *blurFilter = [[GPUImageFastBlurFilter alloc] init];
blurFilter.blurSize = 2;
blurFilter.blurPasses = 3;
[monochromeFilter addTarget:blurFilter];

[saturationFilter prepareForImageCapture];
[monochromeFilter prepareForImageCapture];

[stillImageSource processImage];
image = [blurFilter imageFromCurrentlyProcessedOutput];

这会产生一个接近但不完全存在的图像

模糊似乎不够深,但是当我尝试增加上面的blurSize 时,它变成了网格状,几乎就像一个万花筒。通过放大第二张图像,您实际上可以看到此处的网格。我试图模仿的色调似乎只是洗掉了图像,而不是叠加和混合,我认为 Apple 示例正在这样做。

我尝试根据@BradLarson 在another SO question 中制作的cmets 设置过滤器。是我使用了错误的GPUImage 过滤器来重现这种效果,还是我只是设置错误?

【问题讨论】:

  • 你试过github.com/JagCesar/iOS-blur吗?虽然只能在 iOS7 下运行,但它很棒。
  • iOS-Blur 不是一个可行的解决方案。你不知道苹果在幕后做了什么来使这项工作,它在 iOS 6 上不起作用。

标签: ios image-processing mkmapview core-image gpuimage


【解决方案1】:

好的,我在这里做了一段时间的工作,终于让它正常工作了。我刚刚将 GPUImage 的模糊过滤器的一些更改引入了框架,因此我相信我有一个合理的 Apple 模糊效果复制品,它们用于控制中心视图之类的东西。

以前,我在框架中的模糊使用单个预先计算的半径,影响其强度的唯一方法是调整它们从输入图像中采样像素的间距。由于每个像素的样本数量有限,将采样像素间距的倍数更改为远高于 1.5 会在跳过像素时开始引入严重的块状伪影。

我构建的新高斯模糊实现将预先计算的高斯权重的性能优势与使用任意半径 (sigma) 进行高斯模糊的能力相结合。它通过动态生成着色器来实现这一点,因为它们是各种半径所需的。它还通过使用硬件插值为每个样本点一次读取两个纹素来减少给定模糊半径所需的纹理样本数。

新的 GPUImageiOSBlurFilter 将这个经过调整的任意半径高斯模糊滤镜与颜色校正滤镜相结合,看起来可以复制 Apple 在颜色模糊后对颜色执行的调整。我在我的答案here 中添加了以下比较,但它从左侧的控制中心视图显示 Apple 的内置模糊,在右侧显示我的新 GPUImage 模糊过滤器:

作为提高性能的一种方式(Apple 的模糊似乎发生在 sigma 为 48,这需要为每个像素采样相当大的区域),我在高斯模糊之前使用 4X 下采样,然后使用 4X 上采样.这将需要模糊的像素数量减少了 16 倍,并将模糊 sigma 从 48 减少到 12。iPhone 4S 使用此滤镜可以在大约 30 毫秒内模糊整个屏幕。

正确模糊是一回事。 Apple 仍然没有提供快速获取视图背后的图像内容的方法,因此这很可能会成为快速变化内容的瓶颈。

【讨论】:

  • 所以我已经切换到GPUImageiOSBlurFilter,它为我带来了更快的渲染速度。我不使用它来进行实时模糊,但我确实需要它来模糊图像以显示在UITableViewCells 中,所以必须快速快乐并且确实如此。谢谢!
  • Brad,您能否更新一下 GPUImage 的 pod 规格?旧的 0.1.1 规范不包含 GPUImageiOSBlurFilter。谢谢!
  • @KyrDunenkoff - 我假设你指的是 CocoaPods?我不在那里维护任何东西,甚至我自己也不使用 CocoaPods,所以由负责它的人来指向存储库中的最新版本。我只维护 GitHub 存储库。如果你想要最新的代码,我建议直接从 GitHub 拉取。
  • @BradLarson 嘿布拉德。我想知道模糊总是有浅色背景的原因是什么?例如,即使在模糊黑色图像时,模糊后我总是会以灰色结束。
  • @runmad - 好吧,您需要做的就是移除最后的颜色校正步骤(将 GPUImageLuminanceRangeFilter 与 GPUImageiOSBlurFilter 中的直通 GPUImageFilter 交换)以自行获得模糊。 GPUImageiOSBlurFilter 没有太多内容,因此很容易以这种方式克隆和更改。我什至可以在主高斯模糊类中移动模糊的下/上采样,使其更加简单。
猜你喜欢
  • 2012-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多