Commit c73871a6 by Dmitriy Stepanets

IOS-147: Added new average color calculating logic grabbed from android Palette

parent d0837650
......@@ -23,56 +23,56 @@
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>4</integer>
<integer>3</integer>
</dict>
<key>OneWeatherCorePlayground (Playground) 1.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>67</integer>
<integer>64</integer>
</dict>
<key>OneWeatherCorePlayground (Playground) 10.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>21</integer>
<integer>23</integer>
</dict>
<key>OneWeatherCorePlayground (Playground) 11.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>22</integer>
<integer>24</integer>
</dict>
<key>OneWeatherCorePlayground (Playground) 12.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>23</integer>
<integer>25</integer>
</dict>
<key>OneWeatherCorePlayground (Playground) 13.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>30</integer>
<integer>93</integer>
</dict>
<key>OneWeatherCorePlayground (Playground) 14.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>31</integer>
<integer>94</integer>
</dict>
<key>OneWeatherCorePlayground (Playground) 15.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>32</integer>
<integer>95</integer>
</dict>
<key>OneWeatherCorePlayground (Playground) 16.xcscheme</key>
<dict>
......@@ -100,63 +100,63 @@
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>68</integer>
<integer>65</integer>
</dict>
<key>OneWeatherCorePlayground (Playground) 3.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>69</integer>
<integer>66</integer>
</dict>
<key>OneWeatherCorePlayground (Playground) 4.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>65</integer>
<integer>11</integer>
</dict>
<key>OneWeatherCorePlayground (Playground) 5.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>66</integer>
<integer>12</integer>
</dict>
<key>OneWeatherCorePlayground (Playground) 6.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>67</integer>
<integer>13</integer>
</dict>
<key>OneWeatherCorePlayground (Playground) 7.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>18</integer>
<integer>17</integer>
</dict>
<key>OneWeatherCorePlayground (Playground) 8.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>19</integer>
<integer>18</integer>
</dict>
<key>OneWeatherCorePlayground (Playground) 9.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>20</integer>
<integer>19</integer>
</dict>
<key>OneWeatherCorePlayground (Playground).xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>2</integer>
<integer>4</integer>
</dict>
<key>PG (Playground) 1.xcscheme</key>
<dict>
......@@ -170,42 +170,42 @@
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>24</integer>
<integer>26</integer>
</dict>
<key>PG (Playground) 11.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>25</integer>
<integer>27</integer>
</dict>
<key>PG (Playground) 12.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>26</integer>
<integer>28</integer>
</dict>
<key>PG (Playground) 13.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>27</integer>
<integer>89</integer>
</dict>
<key>PG (Playground) 14.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>28</integer>
<integer>90</integer>
</dict>
<key>PG (Playground) 15.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>29</integer>
<integer>91</integer>
</dict>
<key>PG (Playground) 16.xcscheme</key>
<dict>
......@@ -247,49 +247,49 @@
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>70</integer>
<integer>14</integer>
</dict>
<key>PG (Playground) 5.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>71</integer>
<integer>15</integer>
</dict>
<key>PG (Playground) 6.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>72</integer>
<integer>16</integer>
</dict>
<key>PG (Playground) 7.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>15</integer>
<integer>20</integer>
</dict>
<key>PG (Playground) 8.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>16</integer>
<integer>21</integer>
</dict>
<key>PG (Playground) 9.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>17</integer>
<integer>22</integer>
</dict>
<key>PG (Playground).xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>3</integer>
<integer>2</integer>
</dict>
</dict>
</dict>
......
......@@ -6,19 +6,19 @@
//
import UIKit
import Palette
extension UIImage {
var averageColor: UIColor? {
guard let inputImage = CIImage(image: self) else { return nil }
let extentVector = CIVector(x: inputImage.extent.origin.x, y: inputImage.extent.origin.y, z: inputImage.extent.size.width, w: inputImage.extent.size.height)
let palette = self.createPalette()
var vibrantSwatch = palette.mutedSwatch
if nil == vibrantSwatch {
vibrantSwatch = palette.darkMutedSwatch
}
if nil == vibrantSwatch {
vibrantSwatch = palette.lightMutedSwatch
}
guard let filter = CIFilter(name: "CIAreaAverage", parameters: [kCIInputImageKey: inputImage, kCIInputExtentKey: extentVector]) else { return nil }
guard let outputImage = filter.outputImage else { return nil }
var bitmap = [UInt8](repeating: 0, count: 4)
let context = CIContext(options: [.workingColorSpace: kCFNull!])
context.render(outputImage, toBitmap: &bitmap, rowBytes: 4, bounds: CGRect(x: 0, y: 0, width: 1, height: 1), format: .RGBA8, colorSpace: nil)
return UIColor(red: CGFloat(bitmap[0]) / 255, green: CGFloat(bitmap[1]) / 255, blue: CGFloat(bitmap[2]) / 255, alpha: CGFloat(bitmap[3]) / 255)
return vibrantSwatch?.color
}
}
......@@ -9,6 +9,7 @@ import UIKit
import OneWeatherCore
import InMobiShortsSource
import OneWeatherAnalytics
import Nuke
protocol ShortsManagerDelegate: AnyObject {
func shortsDidChange()
......@@ -24,6 +25,8 @@ class ShortsManager {
}
//Private
private let avgColorQueue = OperationQueue()
private let colorCache = NSCache<NSString, UIColor>()
private let source = InMobiShortSource()
private let log = Logger(componentName: "ShortsManager")
private var isUpdating = false
......@@ -84,4 +87,29 @@ class ShortsManager {
self.shorts[sourceIndex].markAsViewed()
}
func backgroundColor(for short:ShortsItem, shortImage: UIImage, completion:@escaping(_ color: UIColor?,_ shortId: String) -> Void) {
if let cachedColor = colorCache.object(forKey: short.id as NSString) {
completion(cachedColor, short.id)
return
}
avgColorQueue.addOperation {
guard let color = shortImage.averageColor else {
completion(nil, short.id)
return
}
self.colorCache.setObject(color, forKey: short.id as NSString)
completion(color, short.id)
}
// shortImage.averageColor { avgColor in
// guard let color = avgColor else {
// completion(nil)
// return
// }
// self.colorCache.setObject(color, forKey: short.id as NSString)
// completion(color)
// }
}
}
......@@ -18,6 +18,7 @@ class ShortsCollectionViewCell: UICollectionViewCell {
private let imageView = UIImageView()
private let footerView = UIView()
private let footerLabel = UILabel()
private var currentShortId: String?
//Public
weak var delegate: ShortsCollectionCellDelegate?
......@@ -31,30 +32,48 @@ class ShortsCollectionViewCell: UICollectionViewCell {
}
func configure(shortsItem: ShortsItem) {
self.currentShortId = shortsItem.id
footerLabel.text = shortsItem.title
if let image = self.bestImageForCellSize(images: shortsItem.images) {
let resizeOptions = ImageProcessors.Resize(size: self.bounds.size, crop: true)
let cornerRadius = ImageProcessors.RoundedCorners(radius: 12)
let imageRequest = ImageRequest(url: image.url, processors: [resizeOptions, cornerRadius])
Nuke.loadImage(with: imageRequest, into: imageView) {[weak self] result in
ImagePipeline.shared.loadImage(with: imageRequest) { result in
switch result {
case .success(let imageResponse):
onMain {
self?.imageView.image = imageResponse.image
case .success(let response):
ShortsManager.shared.backgroundColor(for: shortsItem, shortImage: response.image) {[weak self] avgColor, shortId in
guard self?.currentShortId == shortId else { return }
if let cachedColor = self?.delegate?.averageColor(forImage: imageResponse.image,
identifier: image.url.absoluteString) {
self?.footerView.backgroundColor = cachedColor
}
else {
self?.footerView.backgroundColor = ThemeManager.currentTheme.containerBackgroundColor
onMain {
if let color = avgColor {
self?.imageView.image = response.image
self?.footerView.backgroundColor = color
}
}
}
default:
break
}
}
// Nuke.loadImage(with: imageRequest, into: imageView) {[weak self] result in
// switch result {
// case .success(let imageResponse):
// ShortsManager.shared.backgroundColor(for: shortsItem, shortImage: imageResponse.image) { avgColor, shortId in
// guard self?.currentShortId == shortId else { return }
//
// onMain {
// if let color = avgColor {
// self?.footerView.backgroundColor = color
// }
// }
// }
// default:
// break
// }
// }
}
else {
imageView.image = nil
......@@ -68,6 +87,7 @@ class ShortsCollectionViewCell: UICollectionViewCell {
override func prepareForReuse() {
super.prepareForReuse()
self.imageView.image = nil
self.footerView.backgroundColor = .clear
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment