[英]How do I extract gradient color of minimum track image at the thumb position?
我想将拇指颜色更改为与最小轨道颜色相同。 当它沿着 slider 移动时,我需要在拇指位置提取颜色。我希望我的 slider 拇指看起来像这样,并在它沿着 slider 移动时根据最小轨道渐变颜色改变颜色。
以下是我创建的渐变代码
func setSlider(slider:UISlider) {
let tgl = CAGradientLayer()
let frame = CGRect(x: 0.0, y: 0.0, width: slider.bounds.width, height: 10.0)
tgl.frame = frame
tgl.colors = [UIColor.black.cgColor, UIColor.red.cgColor, UIColor.yellow.cgColor, UIColor.green.cgColor]
tgl.borderWidth = 1.0
tgl.borderColor = UIColor.gray.cgColor
tgl.cornerRadius = 5.0
tgl.endPoint = CGPoint(x: 1.0, y: 1.0)
tgl.startPoint = CGPoint(x: 0.0, y: 1.0)
UIGraphicsBeginImageContextWithOptions(tgl.frame.size, false, 10.0)
tgl.render(in: UIGraphicsGetCurrentContext()!)
let backgroundImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
slider.setMaximumTrackImage(getBgImage(width: slider.bounds.width), for: .normal)
slider.setMinimumTrackImage(backgroundImage, for: .normal)
}
I tried to fetch color using the following code:
let color = sliderRating.minimumTrackImage(for: .normal)?.getPixelColor(point: CGPoint(x: Int(sender.value), y: 1))
func getPixelColor(point: CGPoint) -> UIColor? {
guard let cgImage = cgImage else { return nil }
let width = Int(size.width)
let height = Int(size.height)
let colorSpace = CGColorSpaceCreateDeviceRGB()
guard let context = CGContext(data: nil,
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: width * 4,
space: colorSpace,
bitmapInfo: CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue)
else {
return nil
}
context.draw(cgImage, in: CGRect(origin: .zero, size: size))
guard let pixelBuffer = context.data else { return nil }
let pointer = pixelBuffer.bindMemory(to: UInt32.self, capacity: width * height)
let pixel = pointer[Int(point.y) * width + Int(point.x)]
let r: CGFloat = CGFloat(red(for: pixel)) / 255
let g: CGFloat = CGFloat(green(for: pixel)) / 255
let b: CGFloat = CGFloat(blue(for: pixel)) / 255
let a: CGFloat = CGFloat(alpha(for: pixel)) / 255
return UIColor(red: r, green: g, blue: b, alpha: a)
}
private func alpha(for pixelData: UInt32) -> UInt8 {
return UInt8((pixelData >> 24) & 255)
}
private func red(for pixelData: UInt32) -> UInt8 {
return UInt8((pixelData >> 16) & 255)
}
private func green(for pixelData: UInt32) -> UInt8 {
return UInt8((pixelData >> 8) & 255)
}
private func blue(for pixelData: UInt32) -> UInt8 {
return UInt8((pixelData >> 0) & 255)
}
private func rgba(red: UInt8, green: UInt8, blue: UInt8, alpha: UInt8) -> UInt32 {
return (UInt32(alpha) << 24) | (UInt32(red) << 16) | (UInt32(green) << 8) | (UInt32(blue) << 0)
}
这是我在 stack overflow 上发现的一个类似问题,以供更多参考:
如何提取拇指 position 处的 uislider 渐变颜色?
我尝试从图像中提取像素颜色,但它只给我白色、灰色和深灰色阴影,但我的轨道有 colors,范围从黑色到绿色。
我得到这样的 output:
问题是您如何确定颜色的point
。
您显示的代码:
let color = sliderRating.minimumTrackImage(for: .normal)?.getPixelColor(point: CGPoint(x: Int(sender.value), y: 1))
很难调试。
让我们把它分开:
// safely unwrap the optional to make sure we get a valid image
if let minImg = sender.minimumTrackImage(for: .normal) {
let x = Int(sender.value)
let y = 1
let point = CGPoint(x: x, y: y)
// to debug this:
print("point:", point)
// safely unwrap the optional returned color
if let color = minImg.getPixelColor(pos: point) {
// do something with color
}
}
默认情况下, slider 的值介于0.0
和1.0
之间。 因此,当您拖动拇指时,您会在调试控制台中看到这个 output:
// lots of these
point: (0.0, 1.0)
point: (0.0, 1.0)
point: (0.0, 1.0)
point: (0.0, 1.0)
point: (0.0, 1.0)
// then when you final get all the way to the right
point: (1.0, 1.0)
如您所见,您没有在图像上得到想要的重点。
你没有提到它,但如果做了这样的事情:
sliderRating.minimumValue = 100
sliderRating.maximumValue = 120
你的x
范围从100
到120
。 同样,不是你想要的点。
您不希望使用.value
,而是希望获得x
的拇指矩形的水平中心,以及y
的图像大小的垂直中心。
试试这样:
@objc func sliderRatingValueChanged(_ sender: UISlider) {
// get the slider's trackRect
let trackR = sender.trackRect(forBounds: sender.bounds)
// get the slider's thumbRect
let thumbR = sender.thumbRect(forBounds: sender.bounds, trackRect: trackR, value: sender.value)
// get the slider's minimumTrackImage
if let minImg = sender.minimumTrackImage(for: .normal) {
// we want point.x to be thumb rect's midX
// we want point.y to be 1/2 the height of the min track image
let point = CGPoint(x: thumbR.midX, y: minImg.size.height * 0.5)
// for debugging:
print("point:", point)
// get the color at point
if let color = minImg.getPixelColor(point: point) {
// set tint color of thumb
sender.thumbTintColor = color
}
}
// now do something with the slider's value?
let value = sender.value
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.