目标
我试图在图像上绘制线性渐变。
设置
我有一个函数调用imageWithGradient
,它使用颜色和imageView来放置带有渐变的图像。我使用storyboard将imageView添加到视图中。
问题
当我在模拟器上尝试代码时,有时会出现渐变,有时不会出现alpha(纯色),有时会翻转渐变。由于我使用相同的颜色运行相同的代码,因此它应该对所有图像应用相同的渐变,但很少这样做。
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var c1 = UIColor(red: 1.0, green: 0, blue: 0, alpha: 0.9).CGColor
var c2 = UIColor(red: 0, green: 0, blue: 0, alpha: 0).CGColor
imageWithGradient(self.imageView1, startColor: c1, endColor: c2)
imageWithGradient(self.imageView2, startColor: c1, endColor: c2)
}
func imageWithGradient(imgView:UIImageView, startColor: CGColor, endColor: CGColor){
var img = UIImage(named:"sample.jpg")!
UIGraphicsBeginImageContext(img.size)
var context = UIGraphicsGetCurrentContext()
img.drawAtPoint(CGPointMake(0, 0))
var colorSpace = CGColorSpaceCreateDeviceRGB()
var startColorComp = CGColorGetComponents(startColor)
var endColorComp = CGColorGetComponents(endColor)
var colorComps = [startColorComp[0], endColorComp[0]]
var locations:[CGFloat] = [0.0, 1.0]
var gradient = CGGradientCreateWithColorComponents(colorSpace, &colorComps, &locations, 2)
var startPoint = CGPointMake(img.size.width/2, img.size.height/2)
var endPoint = CGPointMake(img.size.width/2, img.size.height)
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0)
imgView.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
}
结果
答案 0 :(得分:3)
你实际上是在传递一个未初始化的内存块用于颜色组件。
var colorComps = [startColorComp[0], endColorComp[0]]
创建一个由每种颜色的第一个组件组成的数组,因此有2个组件(甚至不是你想要的组件)
接下来,您将2个元素的数组传递给:
let gradient = CGGradientCreateWithColorComponents(colorSpace, colorComps, locations, 2)
其中colorComps期望接收8个浮点数组,因此其他6个浮点数基本上是随机存储器内容,因此结果差异很大。
您可以使用此功能将颜色分量提取到实际颜色分量的数组中。这构建了颜色的4个组成部分的快速数组(或者有很多组成部分,但它应该是4个)
func CGColorComponents(color:CGColorRef) -> [CGFloat] {
let count = CGColorGetNumberOfComponents(color)
var comps = CGColorGetComponents(color)
var array = [CGFloat]()
for i in 0 ..< count {
array.append(comps.memory)
comps = comps.successor()
}
return array
}
您可以使用以下方法构建适当的组件数组:
let startColorComp = CGColorComponents(startColor)
let endColorComp = CGColorComponents(endColor)
let colorComps = startColorComp + endColorComp
将所有内容放在一起,您可以创建一个覆盖图像渐变的功能:
func imageWithGradient(startColor: CGColor, endColor: CGColor) -> UIImage {
var img = UIImage(named:"img_0002.png")!
UIGraphicsBeginImageContext(img.size)
var context = UIGraphicsGetCurrentContext()
img.drawAtPoint(CGPointMake(0, 0))
let colorSpace = CGColorSpaceCreateDeviceRGB()
let componentCount = CGColorSpaceGetNumberOfComponents(colorSpace)
let startColorComp = CGColorComponents(startColor)
let endColorComp = CGColorComponents(endColor)
let colorComps = startColorComp + endColorComp
let locations:[CGFloat] = [0.0, 1.0]
let gradient = CGGradientCreateWithColorComponents(colorSpace, colorComps, locations, 2)
let startPoint = CGPointMake(img.size.width/2, img.size.height/2)
let endPoint = CGPointMake(img.size.width/2, img.size.height)
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
不完全是如何使用它的,但是如果你真的想要维护你的语义,你应该能够挖掘出这些功能。
更好的是,只需使用CGGradientCreateWithColors
代替:
let gradient = CGGradientCreateWithColors(colorSpace, [startColor, endColor], locations)