2014-04-02 9 views
9

Sposób tworzenia gradientowego koloru wygląda tak, jak po obrazie programowo.Rysowanie gradientu na obrazie w ios

enter image description here

+0

Muszę zastosować go do obrazu jako gradient .. – user2823044

+0

Możesz użyć biblioteki GPUIImage od Brada Larsona, jest dobrze udokumentowana i naprawdę potężna. Ma również wiele funkcji na zdjęciach: https://github.com/BradLarson/GPUImage – foOg

+0

co próbowałeś do tej pory? – vikingosegundo

Odpowiedz

38

Kiedy mówisz „stosuje się go na obraz jako gradient ", masz na myśli maskę (odsłaniając obraz na górze, powodując zanik obrazu) o przejrzyste na dole)? Jeśli to przypadek, można zastosować ten gradientu jako maska, przy użyciu CAGradientLayer:

CAGradientLayer *gradientMask = [CAGradientLayer layer]; 
gradientMask.frame = self.imageView.bounds; 
gradientMask.colors = @[(id)[UIColor whiteColor].CGColor, 
         (id)[UIColor clearColor].CGColor]; 
self.imageView.layer.mask = gradientMask; 

Powyższy robi proste gradientu pionowego (bo domyślnie jest pionowa, liniowy gradient). Ale zapytałeś o startPoint, endPoint i locations. Jeżeli, na przykład, chciałeś maska ​​przykłada się poziomo, zrobiłbyś:

gradientMask.startPoint = CGPointMake(0.0, 0.5); // start at left middle 
gradientMask.endPoint = CGPointMake(1.0, 0.5);  // end at right middle 

jeśli chcesz mieć dwa gradienty, jeden w pierwszej 10%, a drugi w ostatniej 10%, można zrobić:

gradientMask.colors = @[(id)[UIColor clearColor].CGColor, 
         (id)[UIColor whiteColor].CGColor, 
         (id)[UIColor whiteColor].CGColor, 
         (id)[UIColor clearColor].CGColor]; 
gradientMask.locations = @[@0.0, @0.10, @0.90, @1.0]; 

Jeśli chcesz proste gradientu samodzielnie (nie jako maska), można by utworzyć view a następnie dodać do niej warstwę gradientu:

CAGradientLayer *gradient = [CAGradientLayer layer]; 
gradient.frame = view.bounds; 
gradient.colors = @[(id)[UIColor whiteColor].CGColor, 
        (id)[UIColor blackColor].CGColor]; 
[view.layer addSublayer:gradient]; 

Zobacz CAGradientLayerclass reference.

+2

dzięki za pomoc, bur nie mogę zrozumieć punktu początkowego, końcowego i lokalizacji kolorów. – user2823044

+1

@ user2823044 Zaktualizowałem mój przykład ilustrujący 'startPoint',' endPoint' oraz 'lokalizacje'. Nie potrzebujesz ich, biorąc pod uwagę przykład pionowego gradientu, ale jeśli chcesz, aby gradient przechodził od lewej do prawej, możesz użyć 'startPoint' i' endPoint'. Jeśli chcesz, aby gradient nie był równomiernie rozmieszczony w tym zakresie 'startPoint' i' endPoint', możesz użyć 'location' (z którym naprawdę bawiłeś się tylko, gdybyś miał więcej niż dwa' kolory'). – Rob

+0

Jak mogę narysować gradient za pomocą pojedynczego koloru (czarny) z malejącym alfą od dołu do góry – user2823044

0
-(void) drawGradientinBounds: (CGRect) currentBounds withColors:(NSArray*) colors andPercentages:(NSArray *)percentages andGradientDirectionIsVertical:(BOOL)isGradientDirectionVertical 
{ 

    CGContextRef currentContext = UIGraphicsGetCurrentContext(); 

    CGGradientRef glossGradient; 
    CGColorSpaceRef rgbColorspace; 

    size_t num_locations = [percentages count]; 
    CGFloat locations[num_locations]; 
    for(int i=0;i<num_locations;i++) 
     locations[i] = [[percentages objectAtIndex:i] floatValue]; 

    int comps = [colors count]*4; 
    CGFloat components[comps]; 
    for(int i = [colors count]-1;i>=0;i--) 
    { 
     comps--; 
     UIColor *c = [colors objectAtIndex:i]; 
     const CGFloat *cg = CGColorGetComponents([c CGColor]); 
     components[comps] = cg[3]; 
     comps--; 
     components[comps] = cg[2]; 
     comps--; 
     components[comps] = cg[1]; 
     comps--; 
     components[comps] = cg[0]; 
    } 

    rgbColorspace = CGColorSpaceCreateDeviceRGB(); 
    glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations); 

    CGPoint topCenter; 
    CGPoint endCenter; 

    if(isGradientDirectionVertical) 
    { 
     topCenter = CGPointMake(CGRectGetMidX(currentBounds), currentBounds.origin.y); 
     endCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetHeight(currentBounds)+currentBounds.origin.y); 

    } 
    else 
    { 
     topCenter = CGPointMake(currentBounds.origin.x,CGRectGetMidY(currentBounds)); 
     endCenter = CGPointMake(CGRectGetWidth(currentBounds)+currentBounds.origin.x,CGRectGetMidY(currentBounds)); 
    } 
    CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, endCenter, 0); 

    CGGradientRelease(glossGradient); 
    CGColorSpaceRelease(rgbColorspace); 
} 

i wejście do tej metody są granice, colorArray:

[NSArray arrayWithObjects:[UIColor blackColor], [UIColor whiteColor], nil] 

percentageArray:

[NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:1.0], nil] 
2
CAGradientLayer *gradient = [CAGradientLayer layer]; 
gradient.frame = self.view.bounds; 


gradient.startPoint = CGPointMake(1.0, 1.0); //Dark From bottom 
gradient.endPoint = CGPointMake(1.0, 0); 


gradient.colors = [NSArray arrayWithObjects: 
        (id)[[UIColor blackColor] CGColor], 
        (id)[[UIColor clearColor] CGColor], nil]; 


[self.view.layer insertSublayer:gradient atIndex:0]; 
6

Właśnie napisałem rozszerzenie UIImage dla Swift 2.0. Może to jakiś pożytek. Wywołujesz go za pomocą tablicy UIColor (dowolnej liczby) i ramki, w której gradient powinien zostać narysowany.

extension UIImage { 

    class func convertGradientToImage(colors: [UIColor], frame: CGRect) -> UIImage { 

     // start with a CAGradientLayer 
     let gradientLayer = CAGradientLayer() 
     gradientLayer.frame = frame 

     // add colors as CGCologRef to a new array and calculate the distances 
     var colorsRef = [CGColor]() 
     var locations = [NSNumber]() 

     for i in 0 ... colors.count-1 { 
      colorsRef.append(colors[i].CGColor as CGColorRef) 
      locations.append(Float(i)/Float(colors.count-1)) 
     } 

     gradientLayer.colors = colorsRef 
     gradientLayer.locations = locations 

     // now build a UIImage from the gradient 
     UIGraphicsBeginImageContext(gradientLayer.bounds.size) 
     gradientLayer.renderInContext(UIGraphicsGetCurrentContext()!) 
     let gradientImage = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 

     // return the gradient image 
     return gradientImage 
    } 
} 

nazwać to tak:

let colors = [ 
    UIColor.blueColor(), 
    UIColor.greenColor() 
    // and many more if you wish 
] 
let gradientImage = UIImage.convertGradientToImage(colors, frame: navigationBar.bounds) 

i stosować z:

.backgroundColor = UIColor(patternImage: gradientImage) 

lub

.setBackgroundImage(gradientImage, forBarMetrics: .Default) 
+0

Ty piękny, piękny mężczyzna/kobieta/dziecko! Miałem układ renderowania rdzenia graficznego, który działał na 99% obrazów, na których próbowałem narysować gradient, ale zawsze był ten 1%, który nie zdołał narysować obrazu i skończył się rzeźnikiem jakości obrazu, czyniąc go całkowicie zniekształconym/ziarnistym/pikselowym, z warstwą gradientu działa doskonale wszędzie (a przynajmniej tak się wydaje). . – CMash

2

Jest to najlepsze podejście, pracuje dla mnie, jako wymogu

CAGradientLayer *gradientLayer = [CAGradientLayer layer]; 
gradientLayer.frame = yourImageView.layer.bounds; 

gradientLayer.colors = [NSArray arrayWithObjects: 
         (id)[UIColor colorWithWhite:1.0f alpha:1.0f].CGColor, 
         (id)[UIColor colorWithWhite:0.0f alpha:0.9f].CGColor, 
         nil]; 

gradientLayer.locations = [NSArray arrayWithObjects: 
          [NSNumber numberWithFloat:0.0f], 
          [NSNumber numberWithFloat:1.0f], 
          nil]; 

[yourImageView.layer addSublayer:gradientLayer];