2013-10-12 3 views
0

Я рисую круг, как ниже, который я заполняю цветом блока, но в идеале я хотел бы воспроизвести размытие стилей iOS7, тем более, что он сидит поверх фотографии.Репликация iOS7 Стиль gaussian blur?

Я изучил различные способы этого, но все они связаны с UIImage, тогда как это круг, который я рисую. Любой способ сделать это?

- (void)drawCenter:(CGContextRef)contextRef withViewSize:(CGSize)viewSize andCenter:(CGPoint)center 
{ 
    int innerDiameter = viewSize.width - self.thickness; 
    float innerRadius = innerDiameter/2; 

    CGContextSetLineWidth(contextRef, self.thickness); 
    CGRect innerCircle = CGRectMake(center.x - innerRadius, center.y - innerRadius, 
            innerDiameter, innerDiameter); 
    CGContextAddEllipseInRect(contextRef, innerCircle); 
    CGContextClip(contextRef); 
    CGContextClearRect(contextRef, innerCircle); 
    CGContextSetFillColorWithColor(contextRef, self.centerColor.CGColor); 
    CGContextFillRect(contextRef, innerCircle); 
} 
+0

Опишите в деталях окончательный эффект, который вы ищите. Размываете ли вы весь образ за кругом? Или вы хотите представить круг поверх изображения, для которого в круге есть небольшая прозрачность, где вы можете увидеть намек на размытое фоновое изображение, но в остальном остальное изображение не размыто? – Rob

+0

Привет, Роб, да, конечно, это то, что мне нужно, так что это в основном размывает изображение круга, а не изображение позади: http://dribbble.s3.amazonaws.com/users/125948/screenshots/1210251 /live-blur.gif –

ответ

2

Вы можете просто сделать размытие, но подрезать результаты (например, с 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.

+0

Удивительный, я отдам его, когда я получу позже, спасибо за ваше время. –

Смежные вопросы