我试图复制苹果公开发布的iOS 7示例屏幕上的模糊背景:
这个问题建议对下面的内容应用CI过滤器,但这是一个完全不同的方法。很明显,iOS 7并没有捕捉到下面视图的内容,原因有很多:
做一些粗略的测试,截取以下视图的截图,并应用CIGaussianBlur过滤器,使用足够大的半径来模拟iOS 7的模糊风格,即使在模拟器上也需要1-2秒。
iOS 7的模糊视图能够模糊动态视图,比如视频或动画,没有明显的延迟。
有没有人可以假设他们可以使用什么框架来创建这种效果,以及是否有可能使用当前的公共api创建类似的效果?
编辑:(来自评论)我们不知道苹果是怎么做的,但我们能做出一些基本的假设吗?我们可以假设他们在使用硬件,对吧?
效果是否在每个视图中都是自包含的,以至于效果实际上不知道它背后是什么?或者,基于模糊的工作原理,模糊背后的内容必须被考虑进去?
如果效果背后的内容是相关的,我们是否可以假设苹果正在接收以下内容的“feed”,并不断地以模糊的方式渲染它们?
事实上,我敢打赌这很容易实现。它的运作方式或外观可能不会完全像苹果,但可能非常接近。
首先,你需要确定你要呈现的UIView的CGRect。一旦确定了这一点,就只需要获取UI部分的图像,以便对其进行模糊处理。就像这样……
- (UIImage*)getBlurredImage {
// You will want to calculate this in code based on the view you will be presenting.
CGSize size = CGSizeMake(200,200);
UIGraphicsBeginImageContext(size);
[view drawViewHierarchyInRect:(CGRect){CGPointZero, w, h} afterScreenUpdates:YES]; // view is the view you are grabbing the screen shot of. The view that is to be blurred.
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Gaussian Blur
image = [image applyLightEffect];
// Box Blur
// image = [image boxblurImageWithBlur:0.2f];
return image;
}
高斯模糊-推荐
使用苹果提供的UIImage+ImageEffects Category,你会得到一个高斯模糊,看起来很像iOS 7中的模糊。
盒子模糊
你也可以使用下面的boxBlurImageWithBlur: UIImage类别来使用框模糊。这是基于你可以在这里找到的算法。
@implementation UIImage (Blur)
-(UIImage *)boxblurImageWithBlur:(CGFloat)blur {
if (blur < 0.f || blur > 1.f) {
blur = 0.5f;
}
int boxSize = (int)(blur * 50);
boxSize = boxSize - (boxSize % 2) + 1;
CGImageRef img = self.CGImage;
vImage_Buffer inBuffer, outBuffer;
vImage_Error error;
void *pixelBuffer;
CGDataProviderRef inProvider = CGImageGetDataProvider(img);
CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
inBuffer.width = CGImageGetWidth(img);
inBuffer.height = CGImageGetHeight(img);
inBuffer.rowBytes = CGImageGetBytesPerRow(img);
inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);
pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));
if(pixelBuffer == NULL)
NSLog(@"No pixelbuffer");
outBuffer.data = pixelBuffer;
outBuffer.width = CGImageGetWidth(img);
outBuffer.height = CGImageGetHeight(img);
outBuffer.rowBytes = CGImageGetBytesPerRow(img);
error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
if (error) {
NSLog(@"JFDepthView: error from convolution %ld", error);
}
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(outBuffer.data,
outBuffer.width,
outBuffer.height,
8,
outBuffer.rowBytes,
colorSpace,
kCGImageAlphaNoneSkipLast);
CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
UIImage *returnImage = [UIImage imageWithCGImage:imageRef];
//clean up
CGContextRelease(ctx);
CGColorSpaceRelease(colorSpace);
free(pixelBuffer);
CFRelease(inBitmapData);
CGImageRelease(imageRef);
return returnImage;
}
@end
现在你正在计算要模糊的屏幕区域,将它传递到模糊类别中,并接收一个已经模糊的UIImage,现在剩下的就是将这个模糊的图像设置为你将呈现的视图的背景。就像我说的,这将不是一个完美的匹配苹果正在做的,但它仍然看起来很酷。
希望能有所帮助。