【问题标题】:Drawing gradient over image in ios在ios中的图像上绘制渐变
【发布时间】:2014-05-13 16:48:07
【问题描述】:

如何以编程方式创建如下图所示的渐变色。

【问题讨论】:

  • 你可以使用 Brad Larson 的 GPUIImage 库,它有很好的文档并且非常强大。它在图像上也有很多功能:github.com/BradLarson/GPUImage
  • 我需要将它作为渐变应用到图像上..
  • 到目前为止你尝试了什么?
  • 如果使用GPUImage,我应该使用哪个滤镜来实现渐变?

标签: ios objective-c gradient layer


【解决方案1】:

当您说“将其作为渐变应用到图像上”时,您的意思是作为蒙版(在顶部显示图像,在底部将图像淡化为透明)?如果是这种情况,您可以使用 CAGradientLayer 将该渐变应用为蒙版:

CAGradientLayer *gradientMask = [CAGradientLayer layer];
gradientMask.frame = self.imageView.bounds;
gradientMask.colors = @[(id)[UIColor whiteColor].CGColor,
                        (id)[UIColor clearColor].CGColor];
self.imageView.layer.mask = gradientMask;

上面做了一个简单的垂直渐变(因为默认是垂直的,线性渐变)。但是您询问了startPoint、endPoint 和locations。例如,如果您希望水平应用遮罩,您可以:

gradientMask.startPoint = CGPointMake(0.0, 0.5);   // start at left middle
gradientMask.endPoint = CGPointMake(1.0, 0.5);     // end at right middle

如果您想要两个渐变,一个在前 10%,另一个在最后 10%,您可以这样做:

gradientMask.colors = @[(id)[UIColor clearColor].CGColor,
                        (id)[UIColor whiteColor].CGColor,
                        (id)[UIColor whiteColor].CGColor,
                        (id)[UIColor clearColor].CGColor];
gradientMask.locations = @[@0.0, @0.10, @0.90, @1.0];

如果您想要一个简单的渐变本身(而不是作为蒙版),您可以创建一个view,然后将渐变层添加到其中:

CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = view.bounds;
gradient.colors = @[(id)[UIColor whiteColor].CGColor,
                    (id)[UIColor blackColor].CGColor];
[view.layer addSublayer:gradient];

见CAGradientLayerclass reference。

【讨论】:

  • 感谢帮助,但我无法理解颜色的起点、终点和位置。
  • @user2823044 我用startPoint、endPoint 和locations 的插图更新了我的示例。鉴于您的垂直渐变示例,您不需要它们,但如果您希望渐变从左到右,您可以使用startPoint 和endPoint。如果您希望渐变在startPoint 和endPoint 的范围内不均匀分布,您可以使用locations(如果您有两个以上的colors,您只会真正使用它)。跨度>
  • 我怎样才能用单色(黑色)绘制渐变,从下到上降低 alphs
  • Rob,我怀疑添加层会影响内存或添加图像作为渐变更好。这会影响内存泄漏
  • @user2823044 好吧,两者都没有“泄漏”。但是,如果您担心内存消耗,添加渐变图像会比 CAGradientLayer 占用更多内存(并且也比使用 Core Graphics 渐变调用的自定义 drawRect 方法占用更多内存)。当您加载图像时,不要被 PNG/JPEG 文件的小尺寸所误导,而是当加载到内存中时,通常每个像素需要 4 个字节(例如,用于 4 英寸 iPhone 的全屏视网膜分辨率图像将占用 3mb;对于跳到 12mb 的视网膜 iPad)。
【解决方案2】:

我刚刚为 Swift 2.0 编写了一个 UIImage 扩展。也许它有点用处。您可以使用 UIColor 数组(任意数字)和应绘制渐变的框架来调用它。

extension UIImage {

    class func convertGradientToImage(colors: [UIColor], frame: CGRect) -> UIImage {

        // start with a CAGradientLayer
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = frame

        // add colors as CGCologRef to a new array and calculate the distances
        var colorsRef = [CGColor]()
        var locations = [NSNumber]()

        for i in 0 ... colors.count-1 {
            colorsRef.append(colors[i].CGColor as CGColorRef)
            locations.append(Float(i)/Float(colors.count-1))
        }

        gradientLayer.colors = colorsRef
        gradientLayer.locations = locations

        // now build a UIImage from the gradient
        UIGraphicsBeginImageContext(gradientLayer.bounds.size)
        gradientLayer.renderInContext(UIGraphicsGetCurrentContext()!)
        let gradientImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        // return the gradient image
        return gradientImage
    }
}

这样称呼它:

let colors = [
    UIColor.blueColor(),
    UIColor.greenColor()
    // and many more if you wish
]
let gradientImage = UIImage.convertGradientToImage(colors, frame: navigationBar.bounds)

并申请:

.backgroundColor = UIColor(patternImage: gradientImage)

或

.setBackgroundImage(gradientImage, forBarMetrics: .Default)

【讨论】:

  • 你美丽,美丽的男人/女人/孩子!我有一个核心图形渐变渲染设置,它适用于我试图在其上绘制渐变的 99% 的图像,但总是有 1% 的图像无法绘制图像并最终降低了图像的质量,使得这一切都已损坏/颗粒状/像素化。使用渐变层,它在任何地方都可以完美运行(或者看起来如此)。血腥的苹果……
【解决方案3】:
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = self.view.bounds;


gradient.startPoint = CGPointMake(1.0, 1.0); //Dark From bottom
gradient.endPoint = CGPointMake(1.0, 0);


gradient.colors = [NSArray arrayWithObjects:
                   (id)[[UIColor blackColor] CGColor],
                   (id)[[UIColor clearColor] CGColor], nil];


[self.view.layer insertSublayer:gradient atIndex:0];

【讨论】:

    【解决方案4】:

    这是最好的方法,按要求为我工作

    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = yourImageView.layer.bounds;
    
    gradientLayer.colors = [NSArray arrayWithObjects:
                            (id)[UIColor colorWithWhite:1.0f alpha:1.0f].CGColor,
                            (id)[UIColor colorWithWhite:0.0f alpha:0.9f].CGColor,
                            nil];
    
    gradientLayer.locations = [NSArray arrayWithObjects:
                               [NSNumber numberWithFloat:0.0f],
                               [NSNumber numberWithFloat:1.0f],
                               nil];
    
    [yourImageView.layer addSublayer:gradientLayer];
    

    【讨论】:

      【解决方案5】:
      -(void) drawGradientinBounds: (CGRect) currentBounds withColors:(NSArray*) colors andPercentages:(NSArray *)percentages andGradientDirectionIsVertical:(BOOL)isGradientDirectionVertical
      {
      
          CGContextRef currentContext = UIGraphicsGetCurrentContext();
      
          CGGradientRef glossGradient;
          CGColorSpaceRef rgbColorspace;
      
          size_t num_locations = [percentages count];
          CGFloat locations[num_locations];
          for(int i=0;i<num_locations;i++)
              locations[i] = [[percentages objectAtIndex:i] floatValue];
      
          int comps = [colors count]*4;
          CGFloat components[comps];
          for(int i = [colors count]-1;i>=0;i--)
          {
              comps--;
              UIColor *c = [colors objectAtIndex:i];
              const CGFloat *cg = CGColorGetComponents([c CGColor]);
              components[comps] = cg[3];
              comps--;
              components[comps] = cg[2];
              comps--;
              components[comps] = cg[1];
              comps--;
              components[comps] = cg[0];
          }
      
          rgbColorspace = CGColorSpaceCreateDeviceRGB();
          glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);
      
          CGPoint topCenter;
          CGPoint endCenter;
      
          if(isGradientDirectionVertical)
          {
              topCenter = CGPointMake(CGRectGetMidX(currentBounds), currentBounds.origin.y);
              endCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetHeight(currentBounds)+currentBounds.origin.y);
      
          }
          else
          {
              topCenter = CGPointMake( currentBounds.origin.x,CGRectGetMidY(currentBounds));
              endCenter = CGPointMake(CGRectGetWidth(currentBounds)+currentBounds.origin.x,CGRectGetMidY(currentBounds));
          }
          CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, endCenter, 0);
      
          CGGradientRelease(glossGradient);
          CGColorSpaceRelease(rgbColorspace);
      }
      

      并且这个方法的输入是bounds, colorArray:

      [NSArray arrayWithObjects:[UIColor blackColor], [UIColor whiteColor], nil]
      

      百分比数组:

      [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:1.0], nil] 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-22
        • 1970-01-01
        • 1970-01-01
        • 2019-06-16
        • 2017-10-22
        • 1970-01-01
        相关资源
        最近更新 更多