2016-12-29 2 views
1

Я создаю эффект размытия, используя эту функцию ниже в viewDidLoad из ViewControllerИспользование GaussianBlur на изображение в 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 


} 

Но этот кусок кода блоков открывает интерфейс и ViewController через 3-4 секунды отставания. Я не хочу представлять пользовательский интерфейс без blurEffect, а также не хочу, чтобы пользователь ждал 3-4 секунды при открытии viewController. Просьба предоставить оптимальное решение этой проблемы.

+0

Вы уверены, что из-за этого эффекта размытия это занимает больше времени? Вы тестировали, комментируя этот код размытия? – Lion

+0

Да без этой функции вызов временной задержки не наступает –

+0

Можете ли вы представить контроллер представления с исходным изображением и выполнить размытие на фоновом потоке и сделать хороший эффект, чтобы заменить изображение после размытия? – ubiAle

ответ

0

Core Image Programming Guide

Performance Best Practices

следующие методы для достижения наилучшей производительности

  • Не создавайте объект CIContext каждый раз, когда вы оказываете. Контексты хранят много информации о состоянии; более эффективно повторно использовать .
  • Оцените, требуется ли управление приложениями. Не используйте его, если он вам не нужен. См. Раздел «Требуется ли ваше приложение для управления цветом?». Избегайте анимации основной анимации при рендеринге объектов CIImage с использованием контекста GPU . Если вам нужно использовать оба одновременно, вы можете настроить как для использования CPU.
  • Убедитесь, что изображения не превышают пределы ЦП и графического процессора. Пределы размера изображения для объектов CIContext различаются в зависимости от того, использует ли Core Image процессор или графический процессор . Проверьте предел с помощью методов
    inputImageMaximumSize и outputImageMaximumSize.
  • Пользователь, если возможно, меньше изображений. Показатели производительности с количеством выходных пикселей. У вас может быть рендеринг Core Image в уменьшенном виде, текстуре или фреймбуфере . Разрешить Core Animation до высококлассный размер дисплея.
  • Использование функций Core Graphics или Image I/O для обрезки или уменьшения масштаба, например, функции CGImageCreateWithImageInRect или
    CGImageSourceCreateThumbnailAtIndex.
  • Класс UIImageView лучше всего работает со статическими изображениями. Если ваше приложение должно получить максимальную производительность, используйте API более низкого уровня.
  • Избегайте ненужных передач текстур между CPU и GPU. Отметьте прямоугольник, который имеет тот же размер, что и исходное изображение до
    , применяя масштаб шкалы содержимого.
  • Рассмотрите возможность использования более простых фильтров, которые могут давать результаты, аналогичные алгоритмическим фильтрам. Например, CIColorCube может производить вывод
    , аналогичный CISepiaTone, и делать это более эффективно.

  • Воспользуйтесь поддержкой изображения YUV в iOS 6.0 и более поздних версиях. Буферные пиксели пикселей изначально YUV, но большинство обработки изображений
    алгоритмы ожидают данные RBGA. Существует стоимость преобразования между
    двумя. Core Image поддерживает чтение YUB из объектов CVPixelBuffer
    и применение соответствующего цветового преобразования.

Посмотрите GPUImage Брэда Ларсона также.Вы можете использовать его. см. этот ответ. https://stackoverflow.com/a/12336118/1378447

0

Можете ли вы представить контроллер представления с исходным изображением и выполнить размытие на фоновом потоке и сделать приятный эффект, чтобы заменить изображение после размытия?

Возможно, вы могли бы использовать UIVisualEffectView и посмотреть, лучше ли производительность?

Apple некоторое время назад также выпустила пример, где они использовали UIImageEffects для выполнения размытия. Это написано в Obj-C, но вы можете легко использовать его в Swift 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 секунды для изображения, чтобы стать размытие (но это не будет блокировать загрузку другого содержимого пользовательского интерфейса). Если вы не хотите, что задержка времени тоже, то, применяя 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) 
    } 

Изменяя стиль эффекта размытия для .light или .dark и альфа-значение от 0 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() 
    } 
} 

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