Ich möchte einen CIFilter auf ein UI-Element anwenden. Ich habe versucht, es über das .filters-Mitglied auf den Views-Layer anzuwenden. Der Filter wird jedoch nicht angewendet.CIFilter auf UI-Elemente anwenden
Antwort
Hier ist ein Ansatz: Verwenden Sie UIGraphicsGetImageFromCurrentImageContext
, um eine UIImage
zu generieren, wenden Sie den Filter darauf an und überlagern Sie eine Bildansicht, die das gefilterte Bild über Ihrer ursprünglichen Komponente enthält.
Hier ist ein Weg, um mit einer Unschärfe zu tun, dass (taken from my blog):
eine unscharfe Darstellung eines UIView zu bekommen ist ziemlich einfach: Ich brauche ein Bild Kontext zu beginnen, verwenden Sie die renderInContext Methode der Ansicht Schicht in die rendern Kontext und dann eine UIImage aus dem Kontext erhalten:
UIGraphicsBeginImageContextWithOptions(CGSize(width: frame.width, height: frame.height), false, 1)
layer.renderInContext(UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
Nachdem ich das Bild gefüllt haben, es ist ein ziemlich Standard-Workflow eine Gaußsche Unschärfe, um es anzuwenden:
guard let blur = CIFilter(name: "CIGaussianBlur") else
{
return
}
blur.setValue(CIImage(image: image), forKey: kCIInputImageKey)
blur.setValue(blurRadius, forKey: kCIInputRadiusKey)
let ciContext = CIContext(options: nil)
let result = blur.valueForKey(kCIOutputImageKey) as! CIImage!
let boundingRect = CGRect(x: -blurRadius * 4,
y: -blurRadius * 4,
width: frame.width + (blurRadius * 8),
height: frame.height + (blurRadius * 8))
let cgImage = ciContext.createCGImage(result, fromRect: boundingRect)
let filteredImage = UIImage(CGImage: cgImage)
Ein unscharfes Bild wird größer sein als sein Eingabebild, daher muss ich explizit die Größe angeben, die ich in createCGImage
benötige.
Der nächste Schritt ist ein UIImageView
zu meiner Ansicht hinzufügen und alle anderen Ansichten ausblenden. Ich habe UIImageView
-BlurOverlay
subclassed so, dass, wenn es zu entfernen kommt, kann ich sicher sein, ich bin ein nicht Beseitigung bestehender UIImageView
:
let blurOverlay = BlurOverlay()
blurOverlay.frame = boundingRect
blurOverlay.image = filteredImage
subviews.forEach{ $0.hidden = true }
addSubview(blurOverlay)
Wenn es um die de-Unschärfe kommt, möchte ich die letzte, um sicherzustellen, subview ist eine meiner BlurOverlay
es entfernen und sichtbar machen den bestehenden Ansichten:
func unBlur()
{
if let blurOverlay = subviews.last as? BlurOverlay
{
blurOverlay.removeFromSuperview()
subviews.forEach{ $0.hidden = false }
}
}
wenn schließlich ein UIView
zu sehen ist derzeit verschwommen, ich muss nur sehen, wenn seine letzte subview ist ein BlurOverlay
:
var isBlurred: Bool
{
return subviews.last is BlurOverlay
}
Trank Sie für Ihre Antwort. Genau das möchte ich tun. Ich muss einen Filter (perspektivische Transformation) auf einem MKMapView anwenden. Was würdest du dann empfehlen? Die Benutzerinteraktion muss nicht vorhanden sein. Ich denke daran, das MapView niemals der View hinzuzufügen und einfach ein Bild davon zu bekommen, wie du es gesagt hast. Ich werde das MapView jedoch programmatisch so drehen, dass es während der Bewegung eine bestimmte Bildrate haben sollte. Wie kann ich beim Verschieben der Ansicht mehr Bilder erhalten? – Lenny1357
Wenn Sie das Bild in 3D drehen möchten, verwenden Sie das Bild als diffusen Inhalt für ein auf eine Ebene angewendetes SceneKit-Material. Wenn Sie die Punkte einer Perspektiventransformation animieren möchten, werfen Sie einen Blick auf 'CADisplayLink' (aber ich denke, dass Sie mit SceneKit mehr Spaß haben werden :)). –
Ich werde das MapView um eine geografische Koordinate drehen. Und die Rotation um die Koordinate sollte mit einem angewendeten Filter angezeigt werden. Ein einfaches Bild würde in diesem Fall nicht ausreichen. Was würden Sie vorschlagen, um eine Rotation zu zeigen, die der MapView selbst mit einem angewendeten CIFilter verwaltet? Es ist, als würde man ein CIF-Filter auf ein Video anwenden, aber in meinem Fall ist es eine Animation aus dem MapView selbst, die ich zeigen möchte. Ich würde etw. Brauchen. wie der PixelBuffer. Leider denke ich, dass es nicht möglich ist, ein MapView zu erstellen. – Lenny1357