Как сделать радиальный градиент на новом UIImage на iphone - PullRequest
2 голосов
/ 11 апреля 2011

Просто интересно, как визуализировать радиальный градиент (точка> круг) на новый UIImage (iphone). Я видел следующее:

http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_shadings/dq_shadings.html

И это заставило меня подумать, что мне нужно использовать CGShadingRef или CGGradientRef и использовать конструктор UIImage 'imageWithCGImage' для перехода от CG * к UIImage ... но я не могу понять, как.

Любые предложения с благодарностью!

Ответы [ 5 ]

10 голосов
/ 12 апреля 2011

Хорошо, вот суть рабочего решения, дайте мне знать, если я что-то пропустил (например, выпустив дескрипторы / ссылки)

Также опубликовано в моем блоге: http://splinter.com.au/rendering-a-radial-gradient-on-the-iphone-obj

- (UIImage *)radialGradientImage:(CGSize)size start:(float)start end:(float)end centre:(CGPoint)centre radius:(float)radius {
    // Render a radial background
    // http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_shadings/dq_shadings.html

    // Initialise
    UIGraphicsBeginImageContextWithOptions(size, YES, 1);

    // Create the gradient's colours
    size_t num_locations = 2;
    CGFloat locations[2] = { 0.0, 1.0 };
    CGFloat components[8] = { start,start,start, 1.0,  // Start color
        end,end,end, 1.0 }; // End color

    CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
    CGGradientRef myGradient = CGGradientCreateWithColorComponents (myColorspace, components, locations, num_locations);

    // Normalise the 0-1 ranged inputs to the width of the image
    CGPoint myCentrePoint = CGPointMake(centre.x * size.width, centre.y * size.height);
    float myRadius = MIN(size.width, size.height) * radius;

    // Draw it!
    CGContextDrawRadialGradient (UIGraphicsGetCurrentContext(), myGradient, myCentrePoint,
                                 0, myCentrePoint, myRadius,
                                 kCGGradientDrawsAfterEndLocation);

    // Grab it as an autoreleased image
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    // Clean up
    CGColorSpaceRelease(myColorspace); // Necessary?
    CGGradientRelease(myGradient); // Necessary?
    UIGraphicsEndImageContext(); // Clean up
    return image;
}
2 голосов
/ 12 сентября 2012

Вы также можете использовать CoreImage в iOS5 + и использовать Vignette Filter.

- (UIImage *)vignetteImageOfSize:(CGSize)size withImage:(UIImage *)image {  
    UIGraphicsBeginImageContextWithOptions(size, YES, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
    CGContextFillRect(context, CGRectMake(0.0, 0.0, size.width, size.height));

    CIImage *coreImage = [CIImage imageWithCGImage:image.CGImage];
    CGPoint origin = [coreImage extent].origin;
    CGAffineTransform translation =
    CGAffineTransformMakeTranslation(-origin.x, -origin.y);
    coreImage = [coreImage imageByApplyingTransform:translation];

    CIFilter *vignette = [[CIFilter filterWithName:@"CIVignette"] retain];
    [vignette setValue:@1.5 forKey:@"inputRadius"];
    [vignette setValue:@1.5 forKey:@"inputIntensity"];
    [vignette setValue:coreImage forKey:@"inputImage"];

    UIImage *vignetteImage = [UIImage imageWithCIImage:vignette.outputImage];
    [vignette release];

    CGRect imageFrame = CGRectMake(0.0, 0.0, size.width, size.height);
    [image drawInRect:imageFrame];
    UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return renderedImage;
}
1 голос
/ 03 сентября 2015

Я написал этот простой метод здесь (например, поместите его в категорию UIImage)

+ (UIImage *)radialGradientImageWithRadius:(CGFloat)radius StartColor:(UIColor*)startColor EndColor:(UIColor*)endColor ApplyScreenScale:(BOOL)useScreenScale
{
    // Initialize
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(radius * 2, radius * 2), NO, (useScreenScale ? 0.f : 1.f));

    CGContextRef context = UIGraphicsGetCurrentContext();

    // bottom glow gradient
    CGColorSpaceRef colourspace = CGColorSpaceCreateDeviceRGB();

    // build color components
    CGFloat red1 = 0.f, green1 = 0.f, blue1 = 0.f, alpha1 = 0.f;
    [(startColor == nil ? [UIColor clearColor] : startColor) getRed:&red1 green:&green1 blue:&blue1 alpha:&alpha1];
    CGFloat red2 = 0.f, green2 = 0.f, blue2 = 0.f, alpha2 = 0.f;
    [(endColor == nil ? [UIColor clearColor] : endColor) getRed:&red2 green:&green2 blue:&blue2 alpha:&alpha2];

    CGFloat cComponents[] = { red1, green1, blue1, alpha1, red2, green2, blue2, alpha2 };
    CGFloat cGlocations[] = { 0.f, 1.f };

    CGGradientRef gradient = CGGradientCreateWithColorComponents(colourspace, cComponents, cGlocations, 2);
    CGPoint centerPoint = CGPointMake(radius, radius);

    CGContextDrawRadialGradient(context, gradient, centerPoint, 0.f, centerPoint, radius , 0.f);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    CGGradientRelease(gradient);
    CGColorSpaceRelease(colourspace);
    UIGraphicsEndImageContext();

    return image;
}

Примеры использования:

// resulting image size 128x128 px
UIImage* myRadialImage = [UIImage radialGradientImageWithRadius:128.f StartColor:[UIColor greenColor] EndColor:nil ApplyScreenScale:NO]; 

// resulting image size 256x256 px on normal retina display, or 384x384 on iPhone 6 or gre 
UIImage* myRadialImage = [UIImage radialGradientImageWithRadius:128.f StartColor:[UIColor greenColor] EndColor:[UIColor redColor] ApplyScreenScale:YES]; 

Надеюсь, это полезно

1 голос
/ 11 апреля 2011

Вы должны прочитать о Графических контекстах в том же документе, что и раздел, на который вы ссылались. Все рисование происходит в графическом контексте. Если вы хотите создать изображение с радиальным градиентом, линейным градиентом или чем-то еще, вам необходимо:

  • Создайте графический контекст для своего изображения с помощью UIGraphicsBeginImageContextWithOptions .
  • Сделайте любой рисунок, который вы хотите, чтобы появиться на изображении.
  • Вызовите UIGraphicsGetImageFromCurrentImageContext , чтобы получить изображение из контекста. Это дает вам UIImage, поэтому нет необходимости конвертировать из CGImage.
  • Вызовите UIGraphicsEndImageContext , чтобы очистить контекст.
0 голосов
/ 11 октября 2018

Установить радиальный градиент цвета для UIView,

ДЛЯ ГРАДИЕНТА,

extension UIColor {
func colorWithRadialGradient(frame: CGRect, colors: [UIColor]) -> UIColor {
    if frame.width != 0.0 && frame.height != 0.0 {
        let backgroundGradientLayer = CAGradientLayer()
        backgroundGradientLayer.frame = frame
        let cgColors = colors.map({$0.cgColor})
        backgroundGradientLayer.colors = cgColors
        backgroundGradientLayer.type = kCAGradientLayerRadial
        backgroundGradientLayer.startPoint = CGPoint(x: 0.5, y: 0.1)
        UIGraphicsBeginImageContext(backgroundGradientLayer.bounds.size)
        backgroundGradientLayer.render(in: UIGraphicsGetCurrentContext()!)
        let backgroundColorImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return UIColor(patternImage: backgroundColorImage!)
    }
    return .clear
    }
}

(дополнительно) ДЛЯ ВНЕШНЕЙ ТЕНИ,

extension UIView
{
func setGreenCircularShadow() {
    let greenGradient = [UIColor(red: 13/255.0, green: 160/255.0, blue: 110/255.0, alpha: 0.8),UIColor(red: 7/255.0, green: 200/255.0, blue: 128/255.0, alpha: 1.0),UIColor(red: 7/255.0, green: 200/255.0, blue: 128/255.0, alpha: 1.0), UIColor(red: 13/255.0, green: 160/255.0, blue: 110/255.0, alpha: 0.8)]
    self.backgroundColor        = UIColor().colorWithRadialGradient(frame: self.bounds, colors: greenGradient)
    self.layer.shadowColor      = UIColor(red: 7.0/255.0, green: 200.0/255.0, blue: 128.0/255.0, alpha: 1.0).cgColor
    self.layer.shadowOpacity    = 0.33
    self.layer.shadowOffset     = CGSize(width: 0, height: 5.0)
    self.layer.shadowRadius     = 10
    self.layer.shadowPath       = UIBezierPath(rect: self.bounds).cgPath
   }
}

УСТАНОВИТЬ НА UIVIEW

view.layer.cornerRadius = 5.0
view.setGreenCircularShadow()
...