逐渐将UIImage的颜色从RGB更改为灰度

时间:2015-11-05 19:53:32

标签: swift uiimage swift2 rgb grayscale

我在UIImage中有一个UIScrollView,可以从一端滚动到另一端。假设左边是0.0%,右边是100.0%。

UIImage是RGB范围内的彩色图像,我希望根据滚动位置逐渐变为灰度。

我研究了这个,但找不到任何逐步改变它的答案。显然可以立即以光线比例渲染它。

是否有可能在Swift中执行此操作?

修改

感谢Duncan提供技术上正确的答案。这确实有效,但不幸的是滚动时有滞后现象。这就是我使用Joerns解决方案将两个图像放在彼此上方(一个是彩色的,一个是灰度)并相应地更改alpha值的原因。 如果有人想在这里给Duncans建议代码你去:

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)
        }
    }
}

3 个答案:

答案 0 :(得分: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
    }
}

答案 1 :(得分:2)

最简洁的方法可能是设置一个Core Image过滤器,用于回拨图像的颜色饱和度。我不太确定你改变灰度等级是什么意思"取决于滚动位置"。你是说你希望你的图像在左边完全饱和,然后在右边完全灰度,从颜色到B& W逐渐过渡?

为了达到这个效果,我可能会做以下事情:

使用Core图像过滤器创建灰度图像的版本。 将彩色图像放在底部,B& W图像放在上面。然后创建一个线性渐变并将其应用于顶部图像的遮罩层。最终效果是顶部B& W图像将完全覆盖不透明的彩色图像,并在彩色图像透明的地方完全曝光,并且您可以看到B和B的混合。 W图像部分透明。

你可能也可以通过堆叠多个核心图像过滤器来获得相同的效果,但我之前并没有真正做到这一点,只是阅读它。

答案 2 :(得分:1)

考虑使用具有饱和度参数的CoreImage CIColorControls过滤器。只需将饱和度值与标准化滚动位置相关联,瞧,您就可以获得所需的效果。

西蒙

相关问题