2016-11-23 2 views
16

Легко размыть часть представления, имея в виду, что, если содержимое заметок меняется, размытие меняется и в реальном времени.Как инвертировать цвета определенной области UIView?

Мои вопросы

  1. Как сделать эффект переворачивания, и вы можете поставить его на вид и содержимое позади бы перевернутые цвета

  2. Как добавить эффект, который будет знать средний цвет пикселей позади?

В общем, Как получить доступ к пикселям и манипулировать ими? Мой вопрос не о UIImageView, спрашивая о UIView вообще ..

Есть библиотеки, которые делают что-то подобное, но они настолько медленны и не работают так гладко, как размытие!

Спасибо.

+1

проверить этот проект https://github.com/freshking/BKFilterView – Joe

+0

эта библиотека настолько медленная :( – DeyaEldeen

+0

Прочитайте код в библиотеках, которые уже выполняют это, и используйте этот код, чтобы получить представление о том, как создавать свои собственные фильтр. – user3353890

ответ

5

Если вы знаете, как код CIColorKernel, вы будете иметь то, что вам нужно ,

  • В Core Image имеется несколько фильтров размытия, в которых используется GPU, что даст вам необходимую производительность.

  • CIAreaAverage даст вам средний цвет для указанной прямоугольной области.

Core Image Filters

Вот о простом 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 и т. Д.), Но это хороший старт.

Последнее замечание, вы можете связать отдельные фильтры (включая рукописный цвет, warp и общие ядра). Если вы хотите, вы можете связать свой средний цвет по основному виду с размытием и сделать любую инверсию, которую вы хотите, в качестве одного фильтра/эффекта.

1

Я не думаю, что могу полностью ответить на ваш вопрос, но, возможно, я могу указать вам в правильном направлении.

Apple has some documentation on accessing the pixels data from CGImages, но, конечно, для этого требуется, чтобы у вас было изображение для работы в первую очередь. К счастью, вы можете создать образ из UIView, как это:

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

С этим образом вы создали, вы будете иметь возможность манипулировать пиксельные данные, как вы хотите. Возможно, это не самый чистый способ решить вашу проблему, но, возможно, это что-то интересное.

К сожалению, ссылка, которую я предоставил, написана в Objective-C и ей несколько лет, но, возможно, вы можете понять, как ее использовать.

0

1-й Я рекомендую вам расширить UIImageView для этой цели. ref

Хорошо 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() 
    } 
} 

Ваш ответ here

Смежные вопросы