繁体   English   中英

如何在拇指 position 处提取最小轨道图像的渐变颜色?

[英]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:

SS 1

SS 2

问题是您如何确定颜色的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.01.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范围从100120 同样,不是你想要的点。

您不希望使用.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.

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