2013-01-01 16 views
26

Chcę rozmycie obrazu prostokątnego lub okrągłego. Po przeszukaniu go znalazłem, że łatwo jest rozmazać cały obraz, ale trudno jest zamazać określoną część obrazu (prostokątny, okrągły). więc jak to możliwe?Rozmyć określoną część obrazu (prostokątny, okrągły)?

góry dzięki

+0

Co masz na myśli przez "prostokątny lub okrągły"? Czy chcesz, aby określony obszar zamazywał się w kształcie koła? – Jeeter

+0

yup ... chcę rozmazać konkretny obszar rect/cir – iPatel

+0

czy obszar i wygląd kształtu będą stałe lub dynamiczne przez cały okres użytkowania aplikacji? – Jeeter

Odpowiedz

37

enter image description here

Wystarczy ustawić UIImageView nazwę właściwości jako „ImageView” i dodaj następujące cztery metody z tej samej kolejności w pliku implementacji. Ustaw również tryb ImageView na "Odrysuj". Dodaj kategorię UIImage dla efektu rozmycia, jak podano lub użyj dowolnej klasy niestandardowej, będzie działać dla Ciebie.

Metoda 1 - Kadrowanie obrazu

#pragma mark - Cropping the Image 

- (UIImage *)croppIngimageByImageName:(UIImage *)imageToCrop toRect:(CGRect)rect{ 

    CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);  
    UIImage *cropped = [UIImage imageWithCGImage:imageRef]; 
    CGImageRelease(imageRef); 

    return cropped; 


} 

Metoda 2 - Scalanie dwóch obrazów

#pragma mark - Marge two Images 

- (UIImage *) addImageToImage:(UIImage *)img withImage2:(UIImage *)img2 andRect:(CGRect)cropRect{ 

    CGSize size = CGSizeMake(imageView.image.size.width, imageView.image.size.height); 
    UIGraphicsBeginImageContext(size); 

    CGPoint pointImg1 = CGPointMake(0,0); 
    [img drawAtPoint:pointImg1]; 

    CGPoint pointImg2 = cropRect.origin; 
    [img2 drawAtPoint: pointImg2]; 

    UIImage* result = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return result; 
} 

metoda 3 - RoundRect obrazu

#pragma mark - RoundRect the Image 

- (UIImage *)roundedRectImageFromImage:(UIImage *)image withRadious:(CGFloat)radious { 

    if(radious == 0.0f) 
     return image; 

    if(image != nil) { 

     CGFloat imageWidth = image.size.width; 
     CGFloat imageHeight = image.size.height; 

     CGRect rect = CGRectMake(0.0f, 0.0f, imageWidth, imageHeight); 
     UIWindow *window = [[[UIApplication sharedApplication] windows] objectAtIndex:0]; 
     const CGFloat scale = window.screen.scale; 
     UIGraphicsBeginImageContextWithOptions(rect.size, NO, scale); 

     CGContextRef context = UIGraphicsGetCurrentContext(); 

     CGContextBeginPath(context); 
     CGContextSaveGState(context); 
     CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect)); 
     CGContextScaleCTM (context, radious, radious); 

     CGFloat rectWidth = CGRectGetWidth (rect)/radious; 
     CGFloat rectHeight = CGRectGetHeight (rect)/radious; 

     CGContextMoveToPoint(context, rectWidth, rectHeight/2.0f); 
     CGContextAddArcToPoint(context, rectWidth, rectHeight, rectWidth/2.0f, rectHeight, radious); 
     CGContextAddArcToPoint(context, 0.0f, rectHeight, 0.0f, rectHeight/2.0f, radious); 
     CGContextAddArcToPoint(context, 0.0f, 0.0f, rectWidth/2.0f, 0.0f, radious); 
     CGContextAddArcToPoint(context, rectWidth, 0.0f, rectWidth, rectHeight/2.0f, radious); 
     CGContextRestoreGState(context); 
     CGContextClosePath(context); 
     CGContextClip(context); 

     [image drawInRect:CGRectMake(0.0f, 0.0f, imageWidth, imageHeight)]; 

     UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 

     return newImage; 
    } 
    return nil; 
} 

Metoda 4 - dotykowy Przenieś

#pragma mark - Touch Methods 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 


    UIImage *croppedImg = nil; 

    UITouch *touch = [touches anyObject]; 
    CGPoint currentPoint = [touch locationInView:self.imageView]; 

    double ratioW=imageView.image.size.width/imageView.frame.size.width ; 

    double ratioH=imageView.image.size.height/imageView.frame.size.height; 

    currentPoint.x *= ratioW; 
    currentPoint.y *= ratioH; 

    double circleSizeW = 30 * ratioW; 
    double circleSizeH = 30 * ratioH; 


    currentPoint.x = (currentPoint.x - circleSizeW/2<0)? 0 : currentPoint.x - circleSizeW/2; 
    currentPoint.y = (currentPoint.y - circleSizeH/2<0)? 0 : currentPoint.y - circleSizeH/2; 


    CGRect cropRect = CGRectMake(currentPoint.x , currentPoint.y, circleSizeW, circleSizeH); 

    NSLog(@"x %0.0f, y %0.0f, width %0.0f, height %0.0f", cropRect.origin.x, cropRect.origin.y, cropRect.size.width, cropRect.size.height); 

    croppedImg = [self croppIngimageByImageName:self.imageView.image toRect:cropRect]; 

    // Blur Effect 
    croppedImg = [croppedImg imageWithGaussianBlur9]; 

    // Contrast Effect 
    // croppedImg = [croppedImg imageWithContrast:50]; 



    croppedImg = [self roundedRectImageFromImage:croppedImg withRadious:4]; 

    imageView.image = [self addImageToImage:imageView.image withImage2:croppedImg andRect:cropRect]; 
} 

UIImage Kategoria Klasa

UIImage + ImageBlur.h

#import <UIKit/UIKit.h> 

@interface UIImage (ImageBlur) 

- (UIImage *)imageWithGaussianBlur9; 

@end 

UIImage + ImageBlur.m

#import "UIImage+ImageBlur.h" 

@implementation UIImage (ImageBlur) 

- (UIImage *)imageWithGaussianBlur9 { 
    float weight[5] = {0.1270270270, 0.1945945946, 0.1216216216, 0.0540540541, 0.0162162162}; 
    // Blur horizontally 
    UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale); 
    [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height) blendMode:kCGBlendModeNormal alpha:weight[0]]; 
    for (int x = 1; x < 5; ++x) { 
     [self drawInRect:CGRectMake(x, 0, self.size.width, self.size.height) blendMode:kCGBlendModeNormal alpha:weight[x]]; 
     [self drawInRect:CGRectMake(-x, 0, self.size.width, self.size.height) blendMode:kCGBlendModeNormal alpha:weight[x]]; 
    } 
    UIImage *horizBlurredImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    // Blur vertically 
    UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale); 
    [horizBlurredImage drawInRect:CGRectMake(0, 0, self.size.width, self.size.height) blendMode:kCGBlendModeNormal alpha:weight[0]]; 
    for (int y = 1; y < 5; ++y) { 
     [horizBlurredImage drawInRect:CGRectMake(0, y, self.size.width, self.size.height) blendMode:kCGBlendModeNormal alpha:weight[y]]; 
     [horizBlurredImage drawInRect:CGRectMake(0, -y, self.size.width, self.size.height) blendMode:kCGBlendModeNormal alpha:weight[y]]; 
    } 
    UIImage *blurredImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    // 
    return blurredImage; 
} 

@end 

szczęśliwy kodowania ....

+0

dzięki za pomoc mnie .... ale mam błąd .... nie mogę uzyskać metody ImageWithGaussianBlur9 – iPatel

+0

w porządku ... problem jest jasny ... serdeczne dzięki za daj mi ... ale jeśli chcę pokazać prostokątną część wybraną przez użytkownika do rozmycia tego obszaru? jak to jest możliwe ? Jeszcze raz dziękuję – iPatel

+0

To jest metoda klasy UIImage. I o którym wspomniałem w kodzie – junaidsidhu

4

Dodaj następujące Pangesture w widok lub widok obrazu

UIPanGestureRecognizer *panGesture=[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(imageTaped:)]; 
[panGesture setMaximumNumberOfTouches:1]; 
[self.view addGestureRecognizer:panGesture]; 

Metoda rozmycia obrazu

- (void)imageTaped:(UIPanGestureRecognizer *)gestureRecognizer 
{ 

    CIContext *context = [CIContext contextWithOptions:nil]; 
    CGPoint touchLocation = [gestureRecognizer locationInView:self.imgviewMain]; 


    CGRect temp=CGRectMake(touchLocation.x-25, ((self.imgviewMain.frame.size.height-50) - touchLocation.y)+25, 50, 50); 

    CIImage *inputImage0 = [[CIImage alloc] initWithImage:self.imgviewMain.image]; 

    CIImage *inputImage = [[CIImage alloc] initWithImage:[UIImage imageWithCGImage:[context createCGImage:inputImage0 fromRect:temp]]]; 
    CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"]; 
    [blurFilter setDefaults]; 
    [blurFilter setValue: inputImage forKey: @"inputImage"]; 
    [blurFilter setValue: [NSNumber numberWithFloat:0.1] 
        forKey:@"inputRadius"]; 


    CIImage *outputImage = [blurFilter valueForKey: @"outputImage"]; 
    UIImageView *imgtest=[[UIImageView alloc]init]; 

    imgtest.image=[UIImage imageWithCGImage:[context createCGImage:outputImage fromRect:outputImage.extent]]; 



    UIImage *image; 

    UIImage *bottomImage = self.imgviewMain.image; 
      image = imgtest.image;  


    CGSize newSize = CGSizeMake(self.imgviewMain.frame.size.width, self.imgviewMain.frame.size.height); 
    UIGraphicsBeginImageContext(newSize); 

    [bottomImage drawInRect:CGRectMake(0,0,768,1024)]; 

    CGRect newRect2=CGRectMake(temp.origin.x,((self.imgviewMain.frame.size.height-50) - temp.origin.y), image.size.width, image.size.height); 
    image=[self makeRoundedImage:image radius:10]; 

    [image drawInRect:newRect2 blendMode:kCGBlendModeNormal alpha:0.5]; 
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 

    self.imgviewMain.image=newImage; 
    } 

RoundedImage Metoda

-(UIImage *)makeRoundedImage:(UIImage *) image 
         radius: (float) radius; 
{ 
    CALayer *imageLayer = [CALayer layer]; 
    imageLayer.frame = CGRectMake(0, 0, image.size.width, image.size.height); 
    imageLayer.contents = (id) image.CGImage; 

    imageLayer.masksToBounds = YES; 
    imageLayer.cornerRadius = radius; 

    UIGraphicsBeginImageContext(image.size); 
    [imageLayer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    return roundedImage; 
} 
+0

dzięki za pomoc ... ale w twoim kodzie, który framwork muszę dodać ??? #import ??? lub inny ?? – iPatel

+0

yes #import oraz CoreImage i QuartzCore Frameworks – Dhara

1

Wiem, że trochę późno na imprezę, ale może pomóc ktoś, kto stara się uzyskać tej pracy.

Niedawno musiałem go wdrożyć i nie mogłem znaleźć wiele informacji na ten temat w Internecie (szczególnie, jak sprawić, by działało to w przypadku różnych typów skal UIImageView, takich jak Skaluj do wypełnienia, Centrum itp.). Dlatego opracowałem mały projekt, który spełnia dokładnie to, czego oczekujesz.

enter image description here

https://github.com/pauloubuntu/ios-blur-pan-gesture

+0

Nie zapewnia to odpowiedzi na pytanie. Aby skrytykować lub poprosić o wyjaśnienie od autora, pozostaw komentarz pod swoim postem. –

+0

@ VojtechVrbka Nie zgadzam się z twoją opinią. Pytanie dotyczy konkretnie sposobu na rozmycie części obrazu, który jest dokładnie tym, co robi mój przykład. Moim zamiarem stworzenia tego przykładu roboczego i udostępnienia go publicznie jest pomoc przyszłym programistom przy szukaniu tego tematu. Nie wspominając, że zaakceptowana odpowiedź nie dotyczy różnych typów skal UIImageView, co sprawia, że ​​moje rozwiązanie jest lepszym odniesieniem niż przyjęte. –

+0

@ VojtechVrbka AFAIK możesz opublikować link do swojego projektu, o ile dodasz zastrzeżenie, że jesteś programistą, który był używany w wielu różnych wątkach w SO. Jeśli nadal nie zgadzasz się z moim punktem widzenia, sugeruję otwarcie wątku na Meta w celu omówienia, czy jest to dobra praktyka. –

Powiązane problemy