簡體   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