1

viewController の viewDidLoad で以下の関数を使用してぼかし効果を作成しています

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 秒待たされることも望ましくありません。この問題の最適解を教えてください。

4

4 に答える 4

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)
    }

ぼかし効果のスタイルを.lightまたは.darkに変更し、アルファ値を 0 から 1 に変更することで、目的の効果を得ることができます

于 2017-01-05T09:39:17.797 に答える
0

コア イメージ プログラミング ガイド

パフォーマンスのベスト プラクティス

最高のパフォーマンスを得るには、次の方法に従ってください。

  • レンダリングするたびに CIContext オブジェクトを作成しないでください。コンテキストには多くの状態情報が保存されます。それらを再利用する方が効率的です。
  • アプリにカラー マネージメントが必要かどうかを評価します。必要な場合以外は使用しないでください。アプリに色の管理が必要ですか? を参照してください。GPU コンテキストで CIImage オブジェクトをレンダリングするときは、コア アニメーション アニメーションを避けます。両方を同時に使用する必要がある場合は、CPU を使用するように両方をセットアップできます。
  • 画像が CPU と GPU の制限を超えないようにしてください。CIContext オブジェクトの画像サイズの制限は、Core Image が CPU を使用するか GPU を使用するかによって異なります。メソッド
    inputImageMaximumSize および outputImageMaximumSize を使用して制限を確認します。
  • 可能であれば小さい画像を使用してください。パフォーマンスは、出力ピクセル数に比例します。Core Image をより小さいビュー、テクスチャ、またはフレームバッファにレンダリングすることができます。Core Animation が表示サイズにアップスケールできるようにします。
  • CGImageCreateWithImageInRect 関数や CGImageSourceCreateThumbnailAtIndex 関数などの Core Graphics または Image I/O 関数を使用して、クロップまたはダウンサンプリングを
    行います。
  • UIImageView クラスは、静的な画像に最適です。アプリで最高のパフォーマンスを得る必要がある場合は、低レベルの API を使用してください。
  • CPU と GPU 間の不要なテクスチャ転送を回避します。
    コンテンツの倍率を適用する前に、ソース イメージと同じサイズの四角形にレンダリングします。
  • アルゴリズム フィルターと同様の結果を生成できる、より単純なフィルターの使用を検討してください。たとえば、CIColorCube は、CISepiaTone
    と同様の出力をより効率的に生成できます。

  • iOS 6.0 以降での YUV イメージのサポートを活用してください。カメラのピクセル バッファはネイティブの YUV ですが、ほとんどの画像処理
    アルゴリズムは RBGA データを想定しています。2 つの間の変換にはコストがかかり
    ます。Core Image は、CVPixelBuffer オブジェクトから YUB を読み取り
    、適切な色変換を適用することをサポートしています。

Brad Larson の GPUImage もご覧ください。あなたはそれを使いたいかもしれません。この回答を参照してください。https://stackoverflow.com/a/12336118/1378447

于 2017-01-02T08:34:05.623 に答える