kon*_*dev 358 graphics filtering objective-c core-image ios
在新iOS的音乐应用程序中,我们可以看到一个模糊背后的专辑封面.
如何才能完成这样的事情?我已经阅读了文档,但没有找到任何内容.

Jor*_*n H 532
您可以使用它UIVisualEffectView来实现此效果.这是一个本机API,经过微调,性能和电池寿命长,而且易于实现.
迅速:
//only apply the blur if the user hasn't disabled transparency effects
if !UIAccessibility.isReduceTransparencyEnabled {
view.backgroundColor = .clear
let blurEffect = UIBlurEffect(style: .dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
//always fill the view
blurEffectView.frame = self.view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(blurEffectView) //if you have more UIViews, use an insertSubview API to place it where needed
} else {
view.backgroundColor = .black
}
Run Code Online (Sandbox Code Playgroud)
Objective-C的:
//only apply the blur if the user hasn't disabled transparency effects
if (!UIAccessibilityIsReduceTransparencyEnabled()) {
self.view.backgroundColor = [UIColor clearColor];
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
//always fill the view
blurEffectView.frame = self.view.bounds;
blurEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:blurEffectView]; //if you have more UIViews, use an insertSubview API to place it where needed
} else {
self.view.backgroundColor = [UIColor blackColor];
}
Run Code Online (Sandbox Code Playgroud)
如果您以模态方式呈现此视图控制器以模糊基础内容,则需要将模式演示文稿样式设置为"当前上下文"并将背景颜色设置为"清除"以确保基础视图控制器在显示为超出时保持可见.
Jan*_*ano 282
由于屏幕截图中的图像是静态的,因此您可以使用CIGaussianBlurCore Image(需要iOS 6).以下是示例:https://github.com/evanwdavis/Fun-with-Masks/blob/master/Fun%20with%20Masks/EWDBlurExampleVC.m
请注意,这比此页面上的其他选项慢.
#import <QuartzCore/QuartzCore.h>
- (UIImage*) blur:(UIImage*)theImage
{
// ***********If you need re-orienting (e.g. trying to blur a photo taken from the device camera front facing camera in portrait mode)
// theImage = [self reOrientIfNeeded:theImage];
// create our blurred image
CIContext *context = [CIContext contextWithOptions:nil];
CIImage *inputImage = [CIImage imageWithCGImage:theImage.CGImage];
// setting up Gaussian Blur (we could use one of many filters offered by Core Image)
CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
[filter setValue:inputImage forKey:kCIInputImageKey];
[filter setValue:[NSNumber numberWithFloat:15.0f] forKey:@"inputRadius"];
CIImage *result = [filter valueForKey:kCIOutputImageKey];
// CIGaussianBlur has a tendency to shrink the image a little,
// this ensures it matches up exactly to the bounds of our original image
CGImageRef cgImage = [context createCGImage:result fromRect:[inputImage extent]];
UIImage *returnImage = [UIImage imageWithCGImage:cgImage];//create a UIImage for this function to "return" so that ARC can manage the memory of the blur... ARC can't manage CGImageRefs so we need to release it before this function "returns" and ends.
CGImageRelease(cgImage);//release CGImageRef because ARC doesn't manage this on its own.
return returnImage;
// *************** if you need scaling
// return [[self class] scaleIfNeeded:cgImage];
}
+(UIImage*) scaleIfNeeded:(CGImageRef)cgimg {
bool isRetina = [[[UIDevice currentDevice] systemVersion] intValue] >= 4 && [[UIScreen mainScreen] scale] == 2.0;
if (isRetina) {
return [UIImage imageWithCGImage:cgimg scale:2.0 orientation:UIImageOrientationUp];
} else {
return [UIImage imageWithCGImage:cgimg];
}
}
- (UIImage*) reOrientIfNeeded:(UIImage*)theImage{
if (theImage.imageOrientation != UIImageOrientationUp) {
CGAffineTransform reOrient = CGAffineTransformIdentity;
switch (theImage.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
reOrient = CGAffineTransformTranslate(reOrient, theImage.size.width, theImage.size.height);
reOrient = CGAffineTransformRotate(reOrient, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
reOrient = CGAffineTransformTranslate(reOrient, theImage.size.width, 0);
reOrient = CGAffineTransformRotate(reOrient, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
reOrient = CGAffineTransformTranslate(reOrient, 0, theImage.size.height);
reOrient = CGAffineTransformRotate(reOrient, -M_PI_2);
break;
case UIImageOrientationUp:
case UIImageOrientationUpMirrored:
break;
}
switch (theImage.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
reOrient = CGAffineTransformTranslate(reOrient, theImage.size.width, 0);
reOrient = CGAffineTransformScale(reOrient, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
reOrient = CGAffineTransformTranslate(reOrient, theImage.size.height, 0);
reOrient = CGAffineTransformScale(reOrient, -1, 1);
break;
case UIImageOrientationUp:
case UIImageOrientationDown:
case UIImageOrientationLeft:
case UIImageOrientationRight:
break;
}
CGContextRef myContext = CGBitmapContextCreate(NULL, theImage.size.width, theImage.size.height, CGImageGetBitsPerComponent(theImage.CGImage), 0, CGImageGetColorSpace(theImage.CGImage), CGImageGetBitmapInfo(theImage.CGImage));
CGContextConcatCTM(myContext, reOrient);
switch (theImage.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
CGContextDrawImage(myContext, CGRectMake(0,0,theImage.size.height,theImage.size.width), theImage.CGImage);
break;
default:
CGContextDrawImage(myContext, CGRectMake(0,0,theImage.size.width,theImage.size.height), theImage.CGImage);
break;
}
CGImageRef CGImg = CGBitmapContextCreateImage(myContext);
theImage = [UIImage imageWithCGImage:CGImg];
CGImageRelease(CGImg);
CGContextRelease(myContext);
}
return theImage;
}
Run Code Online (Sandbox Code Playgroud)
在WWDC 2013的 "在iOS上实现引导UI"会话中,Apple解释了如何创建模糊背景(在14:30),并提到了applyLightEffect使用Accelerate.framework在示例代码中实现的方法.
GPUImage使用OpenGL着色器来创建动态模糊.它有几种类型的模糊:GPUImageBoxBlurFilter,GPUImageFastBlurFilter,GaussianSelectiveBlur,GPUImageGaussianBlurFilter.甚至还有一个GPUImageiOSBlurFilter"应该完全复制iOS 7控制面板提供的模糊效果"(推文,文章).这篇文章详细而且内容丰富.
-(UIImage *)blurryGPUImage:(UIImage *)image withBlurLevel:(NSInteger)blur {
GPUImageFastBlurFilter *blurFilter = [GPUImageFastBlurFilter new];
blurFilter.blurSize = blur;
UIImage *result = [blurFilter imageByFilteringImage:image];
return result;
}
来自indieambitions.com:使用vImage执行模糊.该算法也用于iOS-RealTimeBlur.
来自Nick Lockwood:https://github.com/nicklockwood/FXBlurView该示例显示滚动视图上的模糊.它使用dispatch_async模糊,然后同步以使用UITrackingRunLoopMode调用更新,因此当UIKit为UIScrollView的滚动提供更多优先级时,模糊不会滞后.尼克的书" iOS核心动画"对此进行了解释,这本书很棒.
iOS-blur这将获取UIToolbar的模糊层并将其放在其他位置.如果您使用此方法,Apple将拒绝您的应用.请参阅https://github.com/mochidev/MDBlurView/issues/4
来自Evadne的博客:LiveFrost:快速,同步的UIView Snapshot Convolving.伟大的代码和伟大的阅读.这篇文章的一些想法:
Andy Matuschak 在推特上说:"你知道,很多地方看起来我们都是在实时做这件事,但这很聪明,技巧娴熟."
在doubleencore.com,他们说"我们发现在大多数情况下,10点的模糊半径加上10点的饱和度增加最能模仿iOS 7的模糊效果".
看看Apple的SBFProceduralWallpaperView的私人标题.
最后,这不是真正的模糊,但请记住,您可以设置rasterizationScale来获取像素化图像:http://www.dimzzy.com/blog/2010/11/blur-effect-for-uiview/
val*_*u17 15
我决定从接受的答案中发布一个书面的Objective-C版本,以便在这个问题中提供更多选项.
- (UIView *)applyBlurToView:(UIView *)view withEffectStyle:(UIBlurEffectStyle)style andConstraints:(BOOL)addConstraints
{
//only apply the blur if the user hasn't disabled transparency effects
if(!UIAccessibilityIsReduceTransparencyEnabled())
{
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:style];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
blurEffectView.frame = view.bounds;
[view addSubview:blurEffectView];
if(addConstraints)
{
//add auto layout constraints so that the blur fills the screen upon rotating device
[blurEffectView setTranslatesAutoresizingMaskIntoConstraints:NO];
[view addConstraint:[NSLayoutConstraint constraintWithItem:blurEffectView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:view
attribute:NSLayoutAttributeTop
multiplier:1
constant:0]];
[view addConstraint:[NSLayoutConstraint constraintWithItem:blurEffectView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:view
attribute:NSLayoutAttributeBottom
multiplier:1
constant:0]];
[view addConstraint:[NSLayoutConstraint constraintWithItem:blurEffectView
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:view
attribute:NSLayoutAttributeLeading
multiplier:1
constant:0]];
[view addConstraint:[NSLayoutConstraint constraintWithItem:blurEffectView
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:view
attribute:NSLayoutAttributeTrailing
multiplier:1
constant:0]];
}
}
else
{
view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.7];
}
return view;
}
Run Code Online (Sandbox Code Playgroud)
如果您只想支持纵向模式,或者我只是在此函数中添加一个标志以便使用它们,那么可以删除约束.
xtr*_*var 13
我不认为我可以发布代码,但上面提到WWDC示例代码的帖子是正确的.这是链接:https://developer.apple.com/downloads/index.action?name = WWDC%202020
您要查找的文件是UIImage上的类别,方法是applyLightEffect.
正如我在评论中所提到的,Apple Blur除了模糊之外还有饱和度和其他事情.一个简单的模糊不会...如果你想模仿他们的风格.
Ada*_*don 12
这是使用UIViewPropertyAnimator添加自定义模糊而不与私有 API 讨价还价的简单方法:
首先,声明类属性:
var blurAnimator: UIViewPropertyAnimator!
Run Code Online (Sandbox Code Playgroud)
然后将您的模糊视图设置为viewDidLoad():
let blurEffectView = UIVisualEffectView()
blurEffectView.backgroundColor = .clear
blurEffectView.frame = view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(blurEffectView)
blurAnimator = UIViewPropertyAnimator(duration: 1, curve: .linear) { [blurEffectView] in
blurEffectView.effect = UIBlurEffect(style: .light)
}
blurAnimator.fractionComplete = 0.15 // set the blur intensity.
Run Code Online (Sandbox Code Playgroud)
注意:此解决方案不适用于UICollectionView/UITableView单元格
我认为最简单的解决方案是覆盖UIToolbar,它在iOS 7中模糊了它背后的一切.它非常狡猾,但它实现起来非常简单,而且速度快!
您可以使用任何视图执行此操作,只需将其作为子类UIToolbar而不是UIView.你甚至可以用它做UIViewController的view特性,例如...
1)创建一个"子类"的新类,UIViewController并选中"With XIB for user interface"框.
2)选择View并转到右侧面板中的身份检查器(alt-command-3).将"班级"更改为UIToolbar.现在转到属性检查器(alt-command-4)并将"背景"颜色更改为"清除颜色".
3)将子视图添加到主视图并将其连接到界面中的IBOutlet.叫它backgroundColorView.它看起来像这样,作为implementation(.m)文件中的私有类.
@interface BlurExampleViewController ()
@property (weak, nonatomic) IBOutlet UIView *backgroundColorView;
@end
Run Code Online (Sandbox Code Playgroud)
4)转到视图控制器implementation(.m)文件并更改-viewDidLoad方法,如下所示:
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.barStyle = UIBarStyleBlack; // this will give a black blur as in the original post
self.backgroundColorView.opaque = NO;
self.backgroundColorView.alpha = 0.5;
self.backgroundColorView.backgroundColor = [UIColor colorWithWhite:0.3 alpha:1];
}
Run Code Online (Sandbox Code Playgroud)
这会给你一个深灰色的视图,模糊背后的一切.没有有趣的业务,没有缓慢的核心图像模糊,使用OS/SDK提供的触手可及的一切.
您可以将此视图控制器的视图添加到另一个视图,如下所示:
[self addChildViewController:self.blurViewController];
[self.view addSubview:self.blurViewController.view];
[self.blurViewController didMoveToParentViewController:self];
// animate the self.blurViewController into view
Run Code Online (Sandbox Code Playgroud)
如果有什么不清楚,请告诉我,我很乐意提供帮助!
UIToolbar在7.0.3中已更改,在使用彩色模糊时可能会产生不良影响.
我们曾经能够使用设置颜色barTintColor,但是如果你以前这样做,你需要将alpha组件设置为小于1.否则你的UIToolbar将是完全不透明的颜色 - 没有模糊.
这可以通过以下方式实现:(牢记self是子类UIToolbar)
UIColor *color = [UIColor blueColor]; // for example
self.barTintColor = [color colorWithAlphaComponent:0.5];
Run Code Online (Sandbox Code Playgroud)
这将为模糊的视图提供蓝色色调.
这是使用CIGaussianBlur在Swift中的快速实现:
func blur(image image: UIImage) -> UIImage {
let radius: CGFloat = 20;
let context = CIContext(options: nil);
let inputImage = CIImage(CGImage: image.CGImage!);
let filter = CIFilter(name: "CIGaussianBlur");
filter?.setValue(inputImage, forKey: kCIInputImageKey);
filter?.setValue("\(radius)", forKey:kCIInputRadiusKey);
let result = filter?.valueForKey(kCIOutputImageKey) as! CIImage;
let rect = CGRectMake(radius * 2, radius * 2, image.size.width - radius * 4, image.size.height - radius * 4)
let cgImage = context.createCGImage(result, fromRect: rect);
let returnImage = UIImage(CGImage: cgImage);
return returnImage;
}
Run Code Online (Sandbox Code Playgroud)
您可以尝试 UIVisualEffectView使用自定义设置作为 -
class BlurViewController: UIViewController {
private let blurEffect = (NSClassFromString("_UICustomBlurEffect") as! UIBlurEffect.Type).init()
override func viewDidLoad() {
super.viewDidLoad()
let blurView = UIVisualEffectView(frame: UIScreen.main.bounds)
blurEffect.setValue(1, forKeyPath: "blurRadius")
blurView.effect = blurEffect
view.addSubview(blurView)
}
}
Run Code Online (Sandbox Code Playgroud)
输出:- 对于 blurEffect.setValue(1...& blurEffect.setValue(2..

如果这对任何人有帮助,这里是我根据 Jordan H 的答案创建的一个快速扩展。它是用 Swift 5 编写的,可以从 Objective C 使用。
extension UIView {
@objc func blurBackground(style: UIBlurEffect.Style, fallbackColor: UIColor) {
if !UIAccessibility.isReduceTransparencyEnabled {
self.backgroundColor = .clear
let blurEffect = UIBlurEffect(style: style)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
//always fill the view
blurEffectView.frame = self.self.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.insertSubview(blurEffectView, at: 0)
} else {
self.backgroundColor = fallbackColor
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意:如果你想模糊UILabel的背景而不影响文本,你应该创建一个容器UIView,将UILabel作为子视图添加到容器UIView中,将UILabel的backgroundColor设置为UIColor.clear,然后调用blurBackground(style :UIBlurEffect.Style,fallbackColor:UIColor)在容器UIView上。下面是用 Swift 5 编写的一个简单示例:
let frame = CGRect(x: 50, y: 200, width: 200, height: 50)
let containerView = UIView(frame: frame)
let label = UILabel(frame: frame)
label.text = "Some Text"
label.backgroundColor = UIColor.clear
containerView.addSubview(label)
containerView.blurBackground(style: .dark, fallbackColor: UIColor.black)
Run Code Online (Sandbox Code Playgroud)
接受的答案是正确的,但这里有一个重要的步骤,如果这个视图 - 你想要模糊的背景 - 使用
[self presentViewController:vc animated:YES completion:nil]
默认情况下,这会消除模糊,因为UIKit会删除演示者的视图,而视图实际上是模糊的.要避免删除,请在上一行之前添加此行
vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
或使用其他Over风格.
| 归档时间: |
|
| 查看次数: |
253242 次 |
| 最近记录: |