Вы можете просто сделать размытие, но подрезать результаты (например, с 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 sample code (требуется заплаченная подписка разработчика) и загрузите 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 high-performance image processing framework.
Этот метод проиллюстрирован на видео WWDC 2013 Implementing Engaging UI on iOS.
Опишите в деталях окончательный эффект, который вы ищите. Размываете ли вы весь образ за кругом? Или вы хотите представить круг поверх изображения, для которого в круге есть небольшая прозрачность, где вы можете увидеть намек на размытое фоновое изображение, но в остальном остальное изображение не размыто? – Rob
Привет, Роб, да, конечно, это то, что мне нужно, так что это в основном размывает изображение круга, а не изображение позади: http://dribbble.s3.amazonaws.com/users/125948/screenshots/1210251 /live-blur.gif –