1

如何用线性渐变填充 PNG UIImage 的非透明区域?我想为 MKAnnotationViews 重用 PNG 形状,但更改每个注释属性的渐变。

4

2 回答 2

1

我最终将 Rob 的一些代码和我在http://coffeeshopped.com/2010/09/iphone-how-to-dynamically-color-a-uiimage找到的 UIImage 的扩展拼凑在一起

+ (UIImage *)imageNamed:(NSString *)name withGradient:(CGGradientRef)gradient
{
    // load the image
    UIImage *img = [UIImage imageNamed:name];

    // begin a new image context, to draw our colored image onto
    UIGraphicsBeginImageContextWithOptions(img.size, NO, [[UIScreen mainScreen] scale]);

    // get a reference to that context we created
    CGContextRef context = UIGraphicsGetCurrentContext();

    // translate/flip the graphics context (for transforming from CG* coords to UI* coords
    CGContextTranslateCTM(context, 0, img.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    // set the blend mode to overlay, and the original image
    CGContextSetBlendMode(context, kCGBlendModeOverlay);
    CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height);

    // set a mask that matches the shape of the image, then draw (overlay) a colored rectangle
    CGContextClipToMask(context, rect, img.CGImage);
    CGContextAddRect(context, rect);

    //gradient
    CGPoint startPoint = CGPointMake(0.0, img.size.height);
    CGPoint endPoint   = CGPointMake(0.0, 0.0);
    CGContextDrawLinearGradient (context, gradient, startPoint, endPoint, 0);

    // generate a new UIImage from the graphics context we drew onto
    UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    CGGradientRelease(gradient);

    //return the color-burned image
    return coloredImg;

}
于 2013-09-05T20:42:30.657 回答
1

要将图像用作渐变的遮罩(即在图像的非透明像素形状中具有渐变),您可以:

  • 创建一个带有渐变的简单视图(您可以创建一个简单的视图UIView并使用addGradientLayerToView下面显示的给它一个渐变,或者您可以提前创建渐变 PNG 并将其添加到您的包中)。

  • 将您的 PNG 作为蒙版应用到该渐变视图:

    UIImage *mask = [UIImage imageNamed:@"mask.png"];
    CALayer *maskLayer = [CALayer layer];
    maskLayer.frame = CGRectMake(0, 0, mask.size.width, mask.size.height);
    maskLayer.contents = (id)[mask CGImage];
    gradientViewToMask.layer.mask = maskLayer;
    

要将渐变应用到透明像素,您可以:

  1. 创建一个带有渐变的新图像:

    - (UIImage *)imageWithGradient:(UIImage *)image
    {
        UIGraphicsBeginImageContextWithOptions(image.size, NO, 1.0);
    
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        size_t locationCount = 2;
        CGFloat locations[2] = { 0.0, 1.0 };
        CGFloat components[8] = { 0.0, 0.8, 0.8, 1.0,   // Start color
                                  0.9, 0.9, 0.9, 1.0 }; // End color
    
        CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    
        CGGradientRef gradient = CGGradientCreateWithColorComponents (colorspace, components, locations, locationCount):
    
        CGPoint startPoint = CGPointMake(0.0, 0.0);
        CGPoint endPoint   = CGPointMake(0.0, image.size.height);
        CGContextDrawLinearGradient (context, gradient, startPoint, endPoint, 0);
    
        CGContextTranslateCTM(context, 0, image.size.height);
        CGContextScaleCTM(context, 1.0, -1.0);
    
        CGContextDrawImage(context, CGRectMake(0.0, 0.0, image.size.width, image.size.height), [image CGImage]);
    
        UIImage *gradientImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        CGGradientRelease(gradient);
        CGColorSpaceRelease(colorspace);
    
        return gradientImage;
    }
    
  2. 您还可以将 a 添加CAGradientLayer到视图,然后将其添加为该UIImageView视图的子视图。

    - (void)addGradientLayerToView:(UIView *)view
    {
        CAGradientLayer *gradient = [CAGradientLayer layer];
        gradient.frame = view.bounds;
        gradient.colors = @[(id)[[UIColor colorWithRed:0.0 green:0.8 blue:0.8 alpha:1.0] CGColor],
                            (id)[[UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0] CGColor]];
        [view.layer insertSublayer:gradient atIndex:0];
    }
    

    请注意,您还必须#import <QuartzCore/QuartzCore.h>将 QuartzCore 框架添加到您的项目中。

于 2013-09-05T15:58:31.323 回答