简体   繁体   English

将渐变应用于UIImage

[英]Applying gradient to UIImage

I want to apply color gradient(from top to bottom) to an image named 'newspaperImage'. 我想将颜色渐变(从上到下)应用于名为“ newspaperImage”的图像。 This is my code using swift language. 这是我使用快速语言的代码。

@IBOutlet weak var newspaperImage: UIImageView!

func imageGradient(){
    let newspaperview = UIView(frame: newspaperImage.frame)
    let gradient = CAGradientLayer()
    gradient.frame = newspaperview.bounds
    let startColor = UIColor(red: 30, green: 113, blue: 79, alpha: 0).cgColor
    let endColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1).cgColor
    gradient.colors = [startColor, endColor]
    newspaperview.layer.insertSublayer(gradient, at: 0)
    newspaperImage.addSubview(newspaperview)
    newspaperImage.bringSubviewToFront(newspaperview)
}

override func viewDidLoad() {
    super.viewDidLoad()

    imageGradient()
}

After running, I find it doesn't work at all. 运行后,我发现它根本不起作用。 Where's the problem? 哪里出问题了?

First lets start with UIColor(red:green:blue:alpha) expects the parameters to be normalised values of 0-1. 首先让我们从UIColor(red:green:blue:alpha)期望参数的标准化值为0-1。

So... 所以...

let startColor = UIColor(red: 30, green: 113, blue: 79, alpha: 0).cgColor

should be 应该

let startColor = UIColor(red: 30/255, green: 113/255, blue: 79/255, alpha: 0).cgColor

Next, I took your basic code and dumped into Playground 接下来,我拿了您的基本代码并转交给Playground

let image = UIImage(named: "Miho_Small.png")

let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
imageView.contentMode = .scaleAspectFit
imageView.image = image

let gradient = CAGradientLayer()
gradient.frame = imageView.bounds
let startColor = UIColor(red: 30/255, green: 113/255, blue: 79/255, alpha: 0).cgColor
let endColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1).cgColor
gradient.colors = [startColor, endColor]
imageView.layer.insertSublayer(gradient, at: 0)

imageView

And it generated... 它产生了...

惊

Okay, that's not what I was expecting, but it's not entirely unsurprising. 好的,这不是我所期望的,但这并不完全令人惊讶。 The CALayer is been painted over the top of the image, because the image is been painted by the UIView 's draw function. CALayer被绘制在图像的顶部,因为该图像是通过UIViewdraw函数draw

Okay, so how can we fix it? 好吧,那我们该如何解决呢? With out going to the extend of making a new images and painting the gradient and image into it, you could make use of a "background" UIView , onto which the layer and UIImageView are applied... 在不进行制作新图像并将渐变和图像绘制到其中的扩展过程中,您可以使用“背景” UIView ,在该UIView上应用图层和UIImageView

let image = UIImage(named: "Miho_Small.png")

let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
imageView.contentMode = .scaleAspectFit
imageView.image = image
imageView.backgroundColor = nil

let backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))

let gradient = CAGradientLayer()
gradient.frame = backgroundView.bounds
let startColor = UIColor(red: 30/255, green: 113/255, blue: 79/255, alpha: 0).cgColor
let endColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1).cgColor
gradient.colors = [startColor, endColor]
backgroundView.layer.insertSublayer(gradient, at: 0)

backgroundView.addSubview(imageView)

backgroundView

which generates... 会产生...

更好

And, that's probably more along the lines of what you're trying to achieve...at a guess 而且,可能更像是您要实现的目标...猜测

:(, the two views can not be overlapped :(,两个视图不能重叠

I don't "overlap", so to speak, I add the UIImageView onto the backgroundView , which contains the CALayer . 我不会“重叠”,可以这么说,我将UIImageView添加到包含CALayerbackgroundView Remember, the view's frame is relative to it's parent's coordinate space. 请记住,视图的frame是相对于其父级的坐标空间的。

In almost all cases, I prefer to use auto layout, and I prefer to use story boards, but those are difficult to make int an answer, so I've done it by hand for this example... 在几乎所有情况下,我都喜欢使用自动布局,并且我喜欢使用情节提要,但是这些很难使int成为答案,因此在此示例中我已经手工完成了...

例

class ViewController: UIViewController {

  override func viewDidLoad() {
    super.viewDidLoad()
    let image = UIImage(named: "Miho_Small.png")

    let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 250, height: 250))
    imageView.contentMode = .scaleAspectFit
    imageView.image = image
    imageView.backgroundColor = nil

    let backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: 250, height: 250))
    backgroundView.translatesAutoresizingMaskIntoConstraints = false

    let gradient = CAGradientLayer()
    gradient.frame = backgroundView.bounds
    let startColor = UIColor(red: 30/255, green: 113/255, blue: 79/255, alpha: 0).cgColor
    let endColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1).cgColor
    gradient.colors = [startColor, endColor]
    backgroundView.layer.insertSublayer(gradient, at: 0)

    backgroundView.addSubview(imageView)

    view.addSubview(backgroundView)

    imageView.leadingAnchor.constraint(equalTo: backgroundView.leadingAnchor).isActive = true
    imageView.trailingAnchor.constraint(equalTo: backgroundView.trailingAnchor).isActive = true
    imageView.topAnchor.constraint(equalTo: backgroundView.topAnchor).isActive = true
    imageView.bottomAnchor.constraint(equalTo: backgroundView.bottomAnchor).isActive = true

    backgroundView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    backgroundView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

    backgroundView.addConstraint(NSLayoutConstraint(item: backgroundView,
                                                    attribute: .width,
                                                    relatedBy: .equal,
                                                    toItem: nil,
                                                    attribute: .notAnAttribute,
                                                    multiplier: 1.0,
                                                    constant: 250))
    backgroundView.addConstraint(NSLayoutConstraint(item: backgroundView,
                                                    attribute: .width,
                                                    relatedBy: .equal,
                                                    toItem: backgroundView,
                                                    attribute: .height,
                                                    multiplier: 1.0,
                                                    constant: 0))


  }


}

For what it's worth, you can checkout the project I used to test the code from GitHub - TestCALayerGradientAndImageOverlay 对于它的价值,您可以从GitHub检出我用来测试代码的项目-TestCALayerGradientAndImageOverlay

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM