Resolved How to create a UIImage RGB gradient with a portion of black programmatically

Discussion in 'iOS Programming' started by troop231, Jan 13, 2014.

  1. troop231, Jan 13, 2014
    Last edited: Jan 13, 2014

    troop231 macrumors 603

    Joined:
    Jan 20, 2010
    #1
    I'm wanting to generate a UIImage that's a RGB gradient that also has a portion of black on the left side. I would like to do this programmatically, instead of having to make the image in Photoshop and using it as an asset in the app.

    I've searched on here and have seen the generation of iOS color wheels before, but nothing like a rectangle below which I mocked in Photoshop:

    [​IMG]

    This will be for letting users change text color as they touch inside of the UIImage.

    I'm not really sure where to begin however, and would appreciate some pointers.

    This is the code I used to make a color wheel before, but I need a rectangle (as shown above) now.

    Code:
         UIGraphicsBeginImageContextWithOptions(CGSizeMake(110, 110), YES, 0.0);
         [[UIColor blackColor] setFill];
         UIRectFill(CGRectMake(0, 0, 110, 110));
         
         int sectors = 360;
         float radius = MIN(100, 100)/2;
         float angle = 2 * M_PI/sectors;
         UIBezierPath *bezierPath;
         
         for (int i = 0; i < sectors; i++)
         {
             CGPoint center = CGPointMake(55, 55);
             bezierPath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:i * angle endAngle:(i + 1) * angle clockwise:YES];
             [bezierPath addLineToPoint:center];
             [bezierPath closePath];
             UIColor *color = [UIColor colorWithHue:((float)i)/sectors saturation:1. brightness:1. alpha:1];
              [color setFill];
              [color setStroke];
             [bezierPath fill];
             [bezierPath stroke];
         }
         
         self.colorWheelImage = UIGraphicsGetImageFromCurrentImageContext();
         UIGraphicsEndImageContext();
    Result of that code:

    [​IMG]
     
  2. troop231, Jan 13, 2014
    Last edited: Jan 13, 2014

    troop231 thread starter macrumors 603

    Joined:
    Jan 20, 2010
    #2
    Edit: still would like to improve this to make it visually appealing with the Hue Saturation Brightness model.

    [​IMG]

    Code:
        self.textColorLayer = [CAGradientLayer layer];
        [self.textColorLayer setFrame:CGRectMake(171, 31, 140, 35)];
        self.textColorLayer.colors =@[(id)[UIColor blackColor].CGColor,(id)[UIColor redColor].CGColor,(id)[UIColor orangeColor].CGColor,(id)[UIColor yellowColor].CGColor,(id)[UIColor greenColor].CGColor,(id)[UIColor cyanColor].CGColor,(id)[UIColor blueColor].CGColor,(id)[UIColor purpleColor].CGColor,(id)[UIColor magentaColor].CGColor];
        
        self.textColorLayer.startPoint =CGPointMake(0, .5);
        self.textColorLayer.endPoint =CGPointMake(1, .5);
        
        self.textColorLayer.cornerRadius = 17.5f;
        
        [self.theCell.layer addSublayer:self.textColorLayer];
     
  3. chown33, Jan 13, 2014
    Last edited: Jan 13, 2014

    chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #3
    Your posted code is drawing a series of filled arcs, each one in a slightly different hue. That is, it's stepping around a circle, and at each step (the filled arc), it's also stepping the hue. In an HSB/HSV color space, hue varies in a circular way, starting from pure red at the East (zero degrees or radians from the horizontal X axis).

    To draw a rectangle, change the code to draw a piece of a rectangle instead of a piece of a circle. Continue stepping the hue as you draw each piece. Since the overall shape is a rectangle, each piece will be a thin vertical rectangle.

    To get black on the left, fill that first, then start stepping the thin rectangles at an offset of 15 or so points.


    If there's something you don't understand about the color-circle code, you need to ask about that. Likewise, if there's something you don't understand about the Hue-Saturation-Brightness color model, you need to ask about that. Otherwise we'll probably assume you understand what's happening in the posted code and why.

    If you copy-pasted that code from somewhere else, tell us where it's from.

    EDIT
    Wow, I'm really getting slow.
     
  4. troop231 thread starter macrumors 603

    Joined:
    Jan 20, 2010
    #4
    I understand the circle code, but don't understand how I'd apply it for a rectangle. The resolved code probably doesn't look as good compared to a bezier path however, and I'd still like to make it with the Hue Saturation Brightness model instead of the CAGradientLayer method above. So technically the question is un-resolved now.
     
  5. troop231, Jan 13, 2014
    Last edited: Jan 13, 2014

    troop231 thread starter macrumors 603

    Joined:
    Jan 20, 2010
    #5
    I'm obviously lost and have been scratching my head at this all day. The below code gives me the resulting image:
    [​IMG]

    Code:
        - (void)viewDidLoad
        {
            [super viewDidLoad];
        
    	UIGraphicsBeginImageContextWithOptions(CGSizeMake(140, 35), YES, 0.0);
        
            int sectors = 255;
            int xAxis = 0;
    
            UIBezierPath *bezierPath;
        
            for (int i = 0; i < sectors; i++)
            {
                xAxis ++;
            
                bezierPath = [UIBezierPath bezierPathWithRect:CGRectMake(xAxis, 0, 5, 35)];
        
                [bezierPath closePath];
                UIColor *color = [UIColor colorWithHue:((float)i)/sectors saturation:1. brightness:1. alpha:1];
                [color setFill];
                [color setStroke];
                [bezierPath fill];
                [bezierPath stroke];
            }
        
            self.colorImage = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
        
            self.theImageView.image = self.colorImage;
            self.theImageView.layer.masksToBounds = YES;
            self.theImageView.layer.cornerRadius = 17.5f;
        }
    
     
  6. troop231 thread starter macrumors 603

    Joined:
    Jan 20, 2010
    #6
    Resolved finally: I ended up using a UISlider to do what I wanted instead, which looks better too.
     

Share This Page