2015-11-05 134 views
1

我在UIScrollView中有一個UIImage,它可以從一端滾動到另一端。可以說左邊是0.0%,右邊是100.0%。逐漸將UIImage的顏色從RGB更改爲灰度

UIImage是RGB範圍內的彩色圖像,我希望根據滾動位置逐漸變爲灰度。

我研究了這個,但找不到任何答案逐漸改變它。顯然可以一次渲染它的射線比例。

有沒有可能在Swift中做到這一點?

編輯

感謝鄧肯技術上正確的答案。這確實有效,但不幸的是它在滾動時滯後。這就是爲什麼我使用Joerns解決方案將兩個圖像放在一起(一個彩色,一個灰度)並相應地更改Alpha值。 如果有人想代碼鄧肯建議,在這裏你去:

if let image = image 
{ 
    let icon = CIImage(CGImage: image) 

    if let filter = CIFilter(name: "CIColorControls") 
    { 
     filter.setValue(icon, forKey: kCIInputImageKey) 
     filter.setValue(0.0, forKey: kCIInputSaturationKey) 

     if let ciImage = filter.outputImage 
     { 
      let context = CIContext(options:nil) 
      let cgImage = context.createCGImage(ciImage, fromRect: ciImage.extent) 

      imageView.image = UIImage(CIImage: cgImage) 
     } 
    } 
} 
+1

您能解釋一下根據滾動位置進行更改的含義嗎?您是否希望飽和度在圖像上從左向右逐漸變化,還是希望圖像的整個可見部分使用根據滾動位置而變化的單個飽和度值?我的回答假設你想要從飽和狀態改變爲左至右。西蒙的回答可以讓你根據滾動位置改變整個當前可見區域的飽和度。 –

+0

@DuncanC看到我上面的編輯 – freshking

+0

@freshking你可以使用CGColorSpaceCreateDeviceGray創建一個上下文並在其上繪製圖像。這比過濾器快10倍。在我的機器0.07121700048446655針對0.6915000081062317使用CIColorControls –

回答

4

我試圖實現對飛一個CoreImage過濾器,但表現得可怕。所以我最終得到了一個帶有灰度的圖像和一個帶有灰度的圖像。這兩個圖像視圖都會堆疊,並且它們的alpha將根據滾動位置進行更改。當您滾動時,結果是從彩色到灰度的平滑過渡:

class ViewController: UIViewController, UIScrollViewDelegate { 

    @IBOutlet weak var scrollView: UIScrollView! 
    let cgImage = UIImage(named: "image.jpg")!.CGImage! 
    let colorImage = UIImageView() 
    let grayscaleImage = UIImageView() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let image = UIImage(named: "image.jpg")! 
     colorImage.image = image 
     scrollView.addSubview(colorImage) 

     let beginImage = CIImage(CGImage: cgImage) 
     let filter = CIFilter(name: "CIColorControls")! 
     filter.setValue(beginImage, forKey: kCIInputImageKey) 
     filter.setValue(0, forKey: kCIInputSaturationKey) 
     grayscaleImage.image = UIImage(CIImage: filter.outputImage!) 
     scrollView.addSubview(grayscaleImage) 

     scrollView.contentSize = image.size 
     colorImage.frame = CGRectMake(0, 0, image.size.width, image.size.height) 
     grayscaleImage.frame = CGRectMake(0, 0, image.size.width, image.size.height) 
    } 

    func scrollViewDidScroll(scrollView: UIScrollView) { 
     let percentage = scrollView.contentOffset.x/(scrollView.contentSize.width - scrollView.bounds.size.width) 
     colorImage.alpha = percentage 
     grayscaleImage.alpha = 1 - percentage 
    } 
} 
+0

酷。所以你使用了我和西蒙的解決方案的混合體。順便說一句,你測試了設備,還是在模擬器上?我發現CI濾波器在設備上表現更好。 –

+0

哦,我不知道。當我在模擬器中測試它的性能非常糟糕時,我甚至都懶得在設備上測試它。不過,我發現問題不在過濾器中,但事實上,每次更換過濾器時都必須更改圖像。當您使用大型圖像時,這不是高性能的。我想這裏是這種情況。 – joern

+0

順便提一下,很高興提供一個解決方案,讓有人去實現它,而不是要求回答者編寫代碼。 –

2

可能做到這一點最徹底的方法是建立一個核心的圖像過濾器,會回撥圖像的色彩飽和度。我不太清楚你的意思是改變灰度「取決於滾動位置」。你是說你希望你的圖像在左邊完全飽和,然後在右邊完全灰度化,並且從顏色逐漸過渡到B?& W?

爲了得到這種效果我可能會做到以下幾點:

使用核心圖像過濾器來創建一個版本,這是灰度圖像。 將彩色圖像放在底部,並在頂部放置B & W圖像。然後創建一個線性漸變並將其應用到頂層圖像的遮罩層。最終的效果是,頂部的圖像將完全覆蓋不透明的彩色圖像,並將彩色圖像完全暴露在透明的位置,並且您會看到2個圖像混合在一起,其中B圖像部分透明。

您可能也可以通過堆疊多個核心圖像過濾器來獲得相同的效果,但我之前沒有真正做過,只是閱讀它。

1

考慮使用具有飽和度參數的CoreImage CIColorControls過濾器。只需將飽和度值與規範化的滾動位置相關聯,瞧,你就會找到你正在尋找的效果。

西蒙