66// Copyright © 2019 Cirno MainasuK. All rights reserved.
77//
88
9- import Cocoa
109import os
11- import DominantColor
10+ import Cocoa
11+ import CoreImage
1212
1313final class PlayerViewController : NSViewController {
1414
1515 private let playerPanelViewController = PlayerPanelViewController ( )
1616 private let playerHistoryViewController = PlayerHistoryViewController ( )
1717
18- // cover
18+ // back cover with blur effect
1919 private let backCoverImageView : MovableImageView = {
2020 let view = MovableImageView ( )
2121 view. wantsLayer = true
2222 view. layer = CALayer ( )
2323 view. layer? . contentsGravity = CALayerContentsGravity . resizeAspectFill
2424 return view
2525 } ( )
26- private let backCoverImageVisualEffectView : NSVisualEffectView = {
27- let visualEffectView = NSVisualEffectView ( )
28- visualEffectView. blendingMode = . withinWindow
29- visualEffectView. material = . hudWindow
30- visualEffectView. isEmphasized = true
31- visualEffectView. state = . active
32- return visualEffectView
33- } ( )
26+
27+ // normal cover
3428 private let coverImageView : MovableImageView = {
3529 let imageView = MovableImageView ( )
3630 imageView. imageScaling = . scaleProportionallyUpOrDown
@@ -129,7 +123,7 @@ extension PlayerViewController {
129123 playerPanelViewController. delegate = self
130124
131125 // V-StackView
132- // - backCoverImageVisualEffectView & coverImageView
126+ // - backCoverImageView & coverImageView
133127 // - playerInfoView
134128 // - playerHistoryViewController
135129
@@ -151,18 +145,9 @@ extension PlayerViewController {
151145 coverImageView. widthAnchor. constraint ( equalToConstant: 300 ) ,
152146 coverImageView. heightAnchor. constraint ( equalTo: coverImageView. widthAnchor) ,
153147 ] )
154-
155- backCoverImageVisualEffectView. translatesAutoresizingMaskIntoConstraints = false
156- view. addSubview ( backCoverImageVisualEffectView, positioned: . below, relativeTo: coverImageView)
157- NSLayoutConstraint . activate ( [
158- backCoverImageVisualEffectView. topAnchor. constraint ( equalTo: coverImageView. topAnchor) ,
159- backCoverImageVisualEffectView. leadingAnchor. constraint ( equalTo: coverImageView. leadingAnchor) ,
160- backCoverImageVisualEffectView. trailingAnchor. constraint ( equalTo: coverImageView. trailingAnchor) ,
161- backCoverImageVisualEffectView. bottomAnchor. constraint ( equalTo: coverImageView. bottomAnchor) ,
162- ] )
163-
148+
164149 backCoverImageView. translatesAutoresizingMaskIntoConstraints = false
165- view. addSubview ( backCoverImageView, positioned: . below, relativeTo: backCoverImageVisualEffectView )
150+ view. addSubview ( backCoverImageView, positioned: . below, relativeTo: stackView )
166151 NSLayoutConstraint . activate ( [
167152 backCoverImageView. topAnchor. constraint ( equalTo: coverImageView. topAnchor) ,
168153 backCoverImageView. leadingAnchor. constraint ( equalTo: coverImageView. leadingAnchor) ,
@@ -278,7 +263,34 @@ extension PlayerViewController {
278263 coverImageView. layer? . add ( transition, forKey: nil )
279264
280265 coverImageView. image = image
281- backCoverImageView. layer? . contents = image
266+ backCoverImageView. layer? . contents = NSImage ( size: coverImageView. frame. size, flipped: true ) { rect -> Bool in
267+ let context = CIContext ( )
268+ guard let tiffData = image. tiffRepresentation, let ciImage = CIImage ( data: tiffData) ,
269+ let clampFilter = CIFilter ( name: " CIAffineClamp " ) ,
270+ let gaussianBlur = CIFilter ( name: " CIGaussianBlur " ) else {
271+ return true
272+ }
273+ let extent = ciImage. extent
274+
275+ clampFilter. setValue ( ciImage, forKey: kCIInputImageKey)
276+ clampFilter. setValue ( NSAffineTransform ( transform: . identity) , forKey: kCIInputTransformKey)
277+ guard let clampFilterOutput = clampFilter. outputImage else {
278+ return true
279+ }
280+
281+ gaussianBlur. setValue ( clampFilterOutput, forKey: kCIInputImageKey)
282+ gaussianBlur. setValue ( 100 , forKey: kCIInputRadiusKey)
283+
284+ guard let outputImage = gaussianBlur. outputImage,
285+ let cgImage = context. createCGImage ( outputImage, from: extent) else {
286+ return true
287+ }
288+
289+ let nsImage = NSImage ( cgImage: cgImage, size: . zero)
290+ nsImage. draw ( in: rect)
291+
292+ return true
293+ }
282294
283295 } else {
284296 coverImageView. image = nil
0 commit comments