2016-12-29 87 views
1

我創建在viewDidLoad中使用此功能,下面的viewController在viewDidLoad中塊UI圖像使用高斯模糊

func applyBlurEffect(image: UIImage){ 

     let imageToBlur = CIImage(image: image)! 
     let blurfilter = CIFilter(name: "CIGaussianBlur")! 
     blurfilter.setValue(10, forKey: kCIInputRadiusKey) 
     blurfilter.setValue(imageToBlur, forKey: "inputImage") 
     let resultImage = blurfilter.value(forKey: "outputImage") as! CIImage 
     let croppedImage: CIImage = resultImage.cropping(to: CGRect(x:0,y: 0,width: imageToBlur.extent.size.width,height: imageToBlur.extent.size.height)) 
     let context = CIContext(options: nil) 
     let blurredImage = UIImage (cgImage: context.createCGImage(croppedImage, from: croppedImage.extent)!) 
     self.backImage.image = blurredImage 


} 

的這段代碼塊的UI和的viewController 3-4秒後,打開一個模糊的效果,但的滯後。我不想在沒有blurEffect的情況下呈現UI,以及我不希望用戶在打開viewController時等待3-4秒。 請提供此問題的最佳解決方案。

+0

你確定因爲這種模糊效果只會花費更多時間嗎?您是否通過評論模糊效果代碼進行測試? – Lion

+0

是沒有這個功能調用沒有時間滯後 –

+0

你可以用原始圖像呈現視圖控制器,並在後臺線程上執行模糊處理,並且在模糊處理準備好後取代圖像會有很好的效果嗎? – ubiAle

回答

0

​​

性能最佳實踐

按照這些做法爲最佳性能:

  • 不要創建CIContext對象每次渲染時間。上下文存儲大量狀態信息;重用 它們會更高效。
  • 評估您的應用是否需要色彩管理。除非你需要它,否則不要使用它。請參閱您的應用是否需要色彩管理?在渲染具有 GPU上下文的CIImage對象時避免使用 核心動畫動畫。如果您需要同時使用兩者,則可以設置 以使用CPU。
  • 確保圖像不超過CPU和GPU限制。 CIContext對象的圖像大小限制取決於Core Image是使用 CPU還是GPU。使用方法
    inputImageMaximumSize和outputImageMaximumSize檢查限制。
  • 如果可能,請使用較小的圖片。性能與輸出像素數量成比例。您可以將核心圖像渲染爲較小的視圖,紋理或幀緩衝區。允許核心動畫 高檔顯示大小。
  • 使用核心圖形或圖像I/O函數進行裁剪或縮小採樣,例如CGImageCreateWithImageInRect或CGImageSourceCreateThumbnailAtIndex函數。
  • UIImageView類最適合靜態圖像。如果您的應用需要獲得最佳性能,請使用較低級別的API。
  • 避免CPU和GPU之間不必要的紋理傳輸。在應用內容比例因子
    之前,渲染到與源圖像大小相同的矩形。
  • 考慮使用更簡單的過濾器,可以產生類似於算法過濾器的結果。例如,CIColorCube可以生成類似於CISepiaTone的輸出
    ,並且可以更高效地完成。

  • 利用在iOS 6.0及更高版本中對YUV圖像的支持。相機像素緩衝區本來就是YUV,但大多數圖像處理算法都需要RBGA數據。兩者之間需要轉換
    。 Core Image支持從CVPixelBuffer對象
    中讀取YUB並應用適當的顏色轉換。

看一看布拉德拉爾森的GPUImage也。你可能想使用它。看到這個答案。 https://stackoverflow.com/a/12336118/1378447

0

就能呈現視圖控制器與原始圖像,並在後臺線程執行模糊,並做了不錯的效果,以取代圖像一旦模糊那些已經準備好?

另外,也許你可以使用UIVisualEffectView,看看性能是否更好?

蘋果在不久前也發佈了他們所使用UIImageEffects執行模糊的例子。這是寫在對象 - 但你可以輕鬆地使用它在斯威夫特https://developer.apple.com/library/content/samplecode/UIImageEffects/Listings/UIImageEffects_UIImageEffects_h.html

0

。利用調度隊列。這一次爲我工作:

func applyBlurEffect(image: UIImage){ 

     DispatchQueue.global(qos: DispatchQoS.QoSClass.userInitiated).async { 

      let imageToBlur = CIImage(image: image)! 
      let blurfilter = CIFilter(name: "CIGaussianBlur")! 
      blurfilter.setValue(10, forKey: kCIInputRadiusKey) 
      blurfilter.setValue(imageToBlur, forKey: "inputImage") 
      let resultImage = blurfilter.value(forKey: "outputImage") as! CIImage 
      let croppedImage: CIImage = resultImage.cropping(to: CGRect(x:0,y: 0,width: imageToBlur.extent.size.width,height: imageToBlur.extent.size.height)) 
      let context = CIContext(options: nil) 
      let blurredImage = UIImage (cgImage: context.createCGImage(croppedImage, from: croppedImage.extent)!) 

      DispatchQueue.main.async { 
       self.backImage.image = blurredImage 
      } 
     } 
    } 

但這種方法會造成3-4秒的延遲對圖像變得模糊(但不會阻止其他UI內容加載)。如果你不希望的時間延遲太,然後應用到UIBlurEffect將ImageView的產生類似的效果:

func applyBlurEffect(image: UIImage){ 

     self.profileImageView.backgroundColor = UIColor.clear 
     let blurEffect = UIBlurEffect(style: .extraLight) 
     let blurEffectView = UIVisualEffectView(effect: blurEffect) 
     blurEffectView.frame = self.backImage.bounds 
     blurEffectView.alpha = 0.5 

     blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight] // for supporting device rotation 
     self.backImage.addSubview(blurEffectView) 
    } 

由0變模糊效果的風格.light.dark和α值1,你可以得到你想要的效果

+0

事情是這樣會讓用戶等待模糊圖像和2-3秒後模糊的圖像將被設置 –

+0

請試試我的編輯答案 –

+0

的第二部分,我已經使用這個UIVisualEffectView但它沒有提供期望的結果。 –

1

GPUImage(https://github.com/BradLarson/GPUImage)模糊的作品真的比CoreImage快得多之一:

extension UIImage { 
    func imageWithGaussianBlur() -> UIImage? { 
    let source = GPUImagePicture(image: self) 
    let gaussianFilter = GPUImageGaussianBlurFilter() 
    gaussianFilter.blurRadiusInPixels = 2.2 
    source?.addTarget(gaussianFilter) 
    gaussianFilter.useNextFrameForImageCapture() 
    source?.processImage() 
    return gaussianFilter.imageFromCurrentFramebuffer() 
    } 
} 

但是小d elay仍然是可能的(取決於圖像大小),所以如果在視圖加載之前無法預處理圖像,我建議先調整圖像大小,模糊並顯示縮略圖,然後在原始圖像處理完成後背景排隊,用模糊的原稿替換縮略圖。