您可以只进行模糊处理,但将结果(例如使用 )剪辑CGContextClip
到圆圈绘制的路径中。以下代码模糊图像中的圆圈,将其亮度增加 10%:
UIImage *original = [UIImage imageNamed:@"image.png"];
UIImage *imageWithBlurredCircle = [original imageWithBlurredCircleWithCenter:CGPointMake(x, y)
radius:75
blur:10
luminosity:0.1];
显然,如果您不想更改亮度,0
请通过luminosity
调整。或者如果你想降低 10% 的亮度,通过-0.1
反正下面这个UIImage
类渲染出来的最终图片如下:
#import "UIImage+Blur.h"
#import <CoreImage/CoreImage.h>
@implementation UIImage (Blur)
- (UIImage *)imageWithBlurredCircleWithCenter:(CGPoint)center radius:(CGFloat)circleRadius blur:(CGFloat)blurRadius luminosity:(CGFloat)luminosity
{
UIImage *blurredImage = [self imageWithBlur:blurRadius luminosity:luminosity];
CGRect frame = CGRectMake(0, 0, self.size.width, self.size.height);
UIGraphicsBeginImageContext(self.size);
CGContextRef context = UIGraphicsGetCurrentContext();
// if you don't want to include the original image, exclude the next five lines
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0.0f, self.size.height);
CGContextScaleCTM(context, 1.0f, -1.0f);
CGContextDrawImage(context, CGRectMake(0, 0, self.size.width, self.size.height), self.CGImage);
CGContextRestoreGState(context);
// clip the drawing to the blurred circle
CGContextSaveGState(context);
CGContextAddArc(context, center.x, center.y, circleRadius, 0, M_PI * 2.0, YES);
CGContextClosePath(context);
CGContextClip(context);
CGContextTranslateCTM(context, 0.0f, self.size.height);
CGContextScaleCTM(context, 1.0f, -1.0f);
CGContextDrawImage(context, frame, blurredImage.CGImage);
CGContextRestoreGState(context);
// now save the image
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
- (UIImage *)imageWithBlur:(CGFloat)radius luminosity:(CGFloat)luminosity
{
CIImage *inputImage = [CIImage imageWithCGImage:self.CGImage]; // self.CIImage;
CIContext *context = [CIContext contextWithOptions:nil];
CIImage *blurImage = [self blurCIImage:inputImage radius:radius];
CIImage *outputImage = [self changeLuminosityOfCIImage:blurImage luminosity:luminosity];
// note, adjust rect because blur changed size of image
CGRect rect = [outputImage extent];
rect.origin.x += (rect.size.width - self.size.width ) / 2;
rect.origin.y += (rect.size.height - self.size.height) / 2;
rect.size = self.size;
CGImageRef cgimg = [context createCGImage:outputImage fromRect:rect];
UIImage *image = [UIImage imageWithCGImage:cgimg];
CGImageRelease(cgimg);
return image;
}
- (CIImage *)blurCIImage:(CIImage *)inputImage radius:(CGFloat)radius
{
if (radius == 0)
return inputImage;
CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
[blurFilter setDefaults];
[blurFilter setValue:inputImage forKey:kCIInputImageKey];
[blurFilter setValue:@(radius) forKey:kCIInputRadiusKey];
return [blurFilter outputImage];
}
- (CIImage *)changeLuminosityOfCIImage:(CIImage *)inputImage luminosity:(CGFloat)luminosity
{
if (luminosity == 0)
return inputImage;
NSParameterAssert(luminosity >= -1.0 && luminosity <= 1.0);
CIFilter *toneCurveFilter = [CIFilter filterWithName:@"CIToneCurve"];
[toneCurveFilter setDefaults];
[toneCurveFilter setValue:inputImage forKey:kCIInputImageKey];
if (luminosity > 0)
{
[toneCurveFilter setValue:[CIVector vectorWithX:0.0 Y:luminosity] forKey:@"inputPoint0"];
[toneCurveFilter setValue:[CIVector vectorWithX:0.25 Y:luminosity + 0.25 * (1 - luminosity)] forKey:@"inputPoint1"];
[toneCurveFilter setValue:[CIVector vectorWithX:0.50 Y:luminosity + 0.50 * (1 - luminosity)] forKey:@"inputPoint2"];
[toneCurveFilter setValue:[CIVector vectorWithX:0.75 Y:luminosity + 0.75 * (1 - luminosity)] forKey:@"inputPoint3"];
[toneCurveFilter setValue:[CIVector vectorWithX:1.0 Y:1.0] forKey:@"inputPoint4"];
}
else
{
[toneCurveFilter setValue:[CIVector vectorWithX:0.0 Y:0.0] forKey:@"inputPoint0"];
[toneCurveFilter setValue:[CIVector vectorWithX:0.25 Y:0.25 * (1 + luminosity)] forKey:@"inputPoint1"];
[toneCurveFilter setValue:[CIVector vectorWithX:0.50 Y:0.50 * (1 + luminosity)] forKey:@"inputPoint2"];
[toneCurveFilter setValue:[CIVector vectorWithX:0.75 Y:0.75 * (1 + luminosity)] forKey:@"inputPoint3"];
[toneCurveFilter setValue:[CIVector vectorWithX:1.0 Y:1 + luminosity] forKey:@"inputPoint4"];
}
return [toneCurveFilter outputImage];
}
@end
或者,如果您前往WWDC 2013 示例代码(需要付费开发者订阅)并下载iOS_UIImageEffects
,然后您可以获取该UIImage+ImageEffects
类别。这提供了一些新方法:
- (UIImage *)applyLightEffect;
- (UIImage *)applyExtraLightEffect;
- (UIImage *)applyDarkEffect;
- (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor;
- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage;
因此,要模糊和成像并使其变亮(给出“毛玻璃”效果),您可以执行以下操作:
UIImage *newImage = [image applyLightEffect];
有趣的是,Apple 的代码并没有使用CIFilter
,而是调用vImageBoxConvolve_ARGB8888
了vImage 高性能图像处理框架。
这种技术在 WWDC 2013 视频Implementation Engaging UI on iOS中有说明。