如何反转UIView特定区域的颜色?

模糊一部分视图很容易,请记住,如果背后的视图内容发生变化,模糊也会实时更改。

我的问题

  1. 如何做一个反转效果,你可以把它放在一个视图和背后的内容将有倒置的颜色

  2. 如何添加一个会知道后面的像素的平均颜色的效果?

一般来说,如何访问像素并操纵它们? 我的问题不是关于UIImageView,一般询问UIView ..

有一些类似的图书馆,但是它们很慢,不能像模糊一样stream畅!

谢谢。

如果你知道如何编写一个CIColorKernel,你将拥有你所需要的。

  • 核心图像有几个模糊filter,所有这些都使用GPU,它会给你你需要的性能。

  • CIAreaAverage将为您提供指定矩形区域的平均颜色。

核心图像filter

这里介绍一下你可以编写的最简单的CIColorKernel。 它交换图像中每个像素的红色和绿色值(注意“grba”而不是“rgba”):

kernel vec4 swapRedAndGreenAmount(__sample s) { return s.grba; } 

把它放到CIColorKernel中,只需使用下面这行代码:

 let swapKernel = CIKernel(string: "kernel vec4 swapRedAndGreenAmount(__sample s) {" + "return s.grba;" + "}" 

@ tww003有很好的代码将视图的图层转换为UIImage。 假设你调用你的映像myUiImage,执行这个swapKernel,你可以:

 let myInputCi = CIImage(image: myUiImage) let myOutputCi = swapKernel.apply(withExtent: myInputCi, arguments: myInputCi) Let myNewImage = UIImage(ciImage: myOutputCi) 

就是这样。 你可以做更多(包括使用CoreGraphics等),但这是一个好的开始。

最后一个注意事项是,可以链接各个filter(包括手写颜色,变形和一般内核)。 如果你愿意的话,你可以将你的颜色平均值在模糊的底层视图上链接起来,做任何你希望的单一过滤/效果的反转。

我不认为我可以完全回答你的问题,但也许我可以指出你正确的方向。

苹果有一些关于从CGImages访问像素数据的文档 ,但是当然这需要你有一个图像来处理。 幸运的是,您可以像这样从UIView创build一个图像:

  UIGraphicsBeginImageContext(view.frame.size) view.layer.render(in: UIGraphicsGetCurrentContext()!) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() 

从你创build的这个图像中,你将能够操纵你想要的像素数据。 这可能不是解决问题的最简洁的方法,但也许是值得探索的事情。

不幸的是,我提供的链接是用Objective-C编写的,已经有几年了,但是也许你可以弄清楚如何使用它。

第一,我会build议你为此目的扩展UIImageView。 REF

好的裁判由乔

你必须重写drawRect方法

 import UIKit @IBDesignable class PortholeView: UIView { @IBInspectable var innerCornerRadius: CGFloat = 10.0 @IBInspectable var inset: CGFloat = 20.0 @IBInspectable var fillColor: UIColor = UIColor.grayColor() @IBInspectable var strokeWidth: CGFloat = 5.0 @IBInspectable var strokeColor: UIColor = UIColor.blackColor() override func drawRect(rect: CGRect) { super.drawRect(rect:rect) // Prep constants let roundRectWidth = rect.width - (2 * inset) let roundRectHeight = rect.height - (2 * inset) // Use EvenOdd rule to subtract portalRect from outerFill // (See https://stackoverflow.com/questions/14141081/uiview-drawrect-draw-the-inverted-pixels-make-a-hole-a-window-negative-space) let outterFill = UIBezierPath(rect: rect) let portalRect = CGRectMake( rect.origin.x + inset, rect.origin.y + inset, roundRectWidth, roundRectHeight) fillColor.setFill() let portal = UIBezierPath(roundedRect: portalRect, cornerRadius: innerCornerRadius) outterFill.appendPath(portal) outterFill.usesEvenOddFillRule = true outterFill.fill() strokeColor.setStroke() portal.lineWidth = strokeWidth portal.stroke() } } 

你的答案在这里