【问题标题】:How to render a radial gradient onto a new UIImage on an iphone如何在 iPhone 上的新 UIImage 上渲染径向渐变
【发布时间】:2011-04-11 05:29:24
【问题描述】:

只是想知道如何在新的 UIImage (iphone) 上渲染径向渐变(点 > 圆)。 我看到了以下内容:

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

这让我觉得我需要使用 CGShadingRef 或 CGGradientRef,并使用 UIImage 的“imageWithCGImage”构造函数从 CG* 转到 UIImage...但我不知道如何。

任何建议都非常感谢!

【问题讨论】:

    标签: iphone objective-c uiimage gradient radial-gradients


    【解决方案1】:

    好的,这是工作解决方案的要点,如果我遗漏了什么(例如释放句柄/引用),请告诉我

    也发在我的博客上: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】:

    您还可以在 iOS5+ 中使用 CoreImage 并使用 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;
    }
    

    【讨论】:

      【解决方案3】:

      您应该在与您链接的部分相同的文档中阅读有关Graphics Contexts 的信息。所有绘图都发生在图形上下文中。如果您想创建具有径向渐变、线性渐变或其他任何内容的图像,您需要:

      【讨论】:

        【解决方案4】:

        我在这里写了这个简单的方法,(比如放到 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]; 
        

        希望有用

        【讨论】:

          【解决方案5】:

          为 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()
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-12-14
            • 1970-01-01
            • 2011-05-28
            • 2012-11-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多