2

I'm applying gradient to UIImage, all i want it to be dark on the bottom and slowly turn to clear or light gray in the middle. It is mostly ok, but i have a problem that my image colors invert in some places under this gradient. This looks very annoying. How do i resolve that?

Here is my method for your convenience.

I have tried picking different blending modes, but it doesn't help. Another question, is how do I make black more intensive in the bottom?

This method will work without any extra code. Start color is [UIColor blackColor] and end color is [UIColor clearColor] :

- (UIImage *)imageWithGradient:(UIImage *)img startColor:(UIColor *)color1 endColor:(UIColor *)color2 {
    UIGraphicsBeginImageContextWithOptions(img.size, NO, img.scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(context, 0, img.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    CGContextSetBlendMode(context, kCGBlendModeDarken); // tried normal here, same results


    CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height);
    CGContextDrawImage(context, rect, img.CGImage);

    // Create gradient
    NSArray *colors = [NSArray arrayWithObjects:(id)color1.CGColor, (id)color2.CGColor, nil];
    CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
    CGGradientRef gradient = CGGradientCreateWithColors(space, (__bridge CFArrayRef)colors, NULL);

    // Apply gradient
    CGContextClipToMask(context, rect, img.CGImage);
    CGContextDrawLinearGradient(context, gradient, CGPointMake(0,0), CGPointMake(0, img.size.height / 2.0), 0);
    UIImage *gradientImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CGGradientRelease(gradient);
    CGColorSpaceRelease(space);

    return gradientImage;
}
Vineet Singh
  • 4,009
  • 1
  • 28
  • 39
Dvole
  • 5,725
  • 10
  • 54
  • 87

4 Answers4

13

Try this

// Set image over layer
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = imageView.frame;

// Add colors to layer
UIColor *centerColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.25];
UIColor *endColor = [UIColor grayColor];
gradient.colors = [NSArray arrayWithObjects:
                               (id)[endColor CGColor],
                               (id)[centerColor CGColor],
                               (id)[endColor CGColor],
                               nil];

[imageView.layer insertSublayer:gradient atIndex:0];

Just change array of gradient.colors depend on your requirements.

Navnath Godse
  • 2,233
  • 2
  • 23
  • 32
  • 2
    For folks trying to achieve the same in Swift (imageView with gradient), make sure your colors array is of type [CGColor] and not [UIColor]. I did not receive any errors for this, but instead this code was ignored (view was not affected). Found it [in this answer](http://stackoverflow.com/a/24380968/1423874). – Shahar Oct 18 '14 at 22:58
5

Navnath answer in Swift

var gradient = CAGradientLayer()
gradient.frame = imageView.frame
gradient.colors = [
    UIColor(white: 0, alpha: 0.25).CGColor,
    UIColor.grayColor().CGColor, 
    UIColor(white: 0, alpha: 0.25).CGColor
]
imageView.layer.insertSublayer(gradient, atIndex: 0)

Hope you find it useful

Francis Reynolds
  • 476
  • 6
  • 18
1

Slight correction to Navnath's and Francis's answers... gradient.frame needs to be set to imageView.bounds:

gradient.frame = imageView.bounds
chinjazz
  • 135
  • 1
  • 2
  • 13
0

Try just changing the alpha to get the desired result. Place the layer over top of your existing image.

Mark McCorkle
  • 9,349
  • 2
  • 32
  • 42