2016-11-23 27 views
16

模糊一部分視圖很容易,請記住,如果視圖背後的內容發生變化,模糊也會實時更改。如何反轉UIView特定區域的顏色?

我的問題

  1. 如何使一個倒置的效果,你可以把它在一個視圖,後面的內容會反色

  2. 如何添加會知道後面的像素的平均顏色的效果?

一般來說,如何訪問像素並操作它們? 我的問題不是關於UIImageView,總體上詢問UIView ..

有一些類似庫的庫,但它們很慢並且不像模糊一樣運行!

謝謝。

+1

檢查這個項目https://github.com/freshking/BKFilterView – Joe

+0

這個庫很慢:( – DeyaEldeen

+0

閱讀庫中的代碼已經完成了這一點,並使用該代碼得到如何建立自己的想法過濾。 – user3353890

回答

5

如果你知道如何編寫CIColorKernel,你就會有你需要什麼。

  • 核心圖像有幾個模糊濾鏡,所有這些都使用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等),但這是一個好的開始。最後一個注意事項是,您可以鏈接各個過濾器(包括手寫顏色,變形和一般內核)。如果你願意的話,你可以將模糊的顏色平均值與底層視圖相關聯,並將你希望的任何一種反轉作爲單個過濾器/效果。

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

1st我建議您爲此擴展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