forked from shadowfacts/Tusker
Fix low resolution avatars being shown on profile
This commit is contained in:
parent
2761c05a01
commit
d1c45a87e6
|
@ -34,10 +34,10 @@ class ImageCache {
|
||||||
self.cache = ImageDataCache(name: name, memoryExpiry: memoryExpiry, diskExpiry: diskExpiry, storeOriginalDataInMemory: diskExpiry == nil, desiredPixelSize: pixelSize)
|
self.cache = ImageDataCache(name: name, memoryExpiry: memoryExpiry, diskExpiry: diskExpiry, storeOriginalDataInMemory: diskExpiry == nil, desiredPixelSize: pixelSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func get(_ url: URL, completion: ((Data?, UIImage?) -> Void)?) -> Request? {
|
func get(_ url: URL, loadOriginal: Bool = false, completion: ((Data?, UIImage?) -> Void)?) -> Request? {
|
||||||
let key = url.absoluteString
|
let key = url.absoluteString
|
||||||
if !ImageCache.disableCaching,
|
if !ImageCache.disableCaching,
|
||||||
let entry = try? cache.get(key) {
|
let entry = try? cache.get(key, loadOriginal: loadOriginal) {
|
||||||
if let completion = completion {
|
if let completion = completion {
|
||||||
backgroundQueue.async {
|
backgroundQueue.async {
|
||||||
completion(entry.data, entry.image)
|
completion(entry.data, entry.image)
|
||||||
|
@ -73,7 +73,7 @@ class ImageCache {
|
||||||
private func createGroup(url: URL) -> RequestGroup {
|
private func createGroup(url: URL) -> RequestGroup {
|
||||||
let group = RequestGroup(url: url) { (data, image) in
|
let group = RequestGroup(url: url) { (data, image) in
|
||||||
if let data = data {
|
if let data = data {
|
||||||
try? self.cache.set(url.absoluteString, data: data)
|
try? self.cache.set(url.absoluteString, data: data, image: image)
|
||||||
}
|
}
|
||||||
self.groups.removeValueWithoutReturning(forKey: url)
|
self.groups.removeValueWithoutReturning(forKey: url)
|
||||||
}
|
}
|
||||||
|
@ -85,8 +85,8 @@ class ImageCache {
|
||||||
return try? cache.getData(url.absoluteString)
|
return try? cache.getData(url.absoluteString)
|
||||||
}
|
}
|
||||||
|
|
||||||
func get(_ url: URL) -> ImageDataCache.Entry? {
|
func get(_ url: URL, loadOriginal: Bool = false) -> ImageDataCache.Entry? {
|
||||||
return try? cache.get(url.absoluteString)
|
return try? cache.get(url.absoluteString, loadOriginal: loadOriginal)
|
||||||
}
|
}
|
||||||
|
|
||||||
func cancelWithoutCallback(_ url: URL) {
|
func cancelWithoutCallback(_ url: URL) {
|
||||||
|
|
|
@ -41,8 +41,9 @@ class ImageDataCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func get(_ key: String) throws -> Entry? {
|
func get(_ key: String, loadOriginal: Bool) throws -> Entry? {
|
||||||
if let memoryEntry = try? memory.object(forKey: key) {
|
if storeOriginalDataInMemory || !loadOriginal,
|
||||||
|
let memoryEntry = try? memory.object(forKey: key) {
|
||||||
return memoryEntry
|
return memoryEntry
|
||||||
} else if let disk = self.disk,
|
} else if let disk = self.disk,
|
||||||
let data = try? disk.object(forKey: key),
|
let data = try? disk.object(forKey: key),
|
||||||
|
@ -54,15 +55,15 @@ class ImageDataCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getImage(_ key: String) throws -> UIImage? {
|
func getImage(_ key: String) throws -> UIImage? {
|
||||||
return try get(key)?.image
|
return try get(key, loadOriginal: false)?.image
|
||||||
}
|
}
|
||||||
|
|
||||||
func getData(_ key: String) throws -> Data? {
|
func getData(_ key: String) throws -> Data? {
|
||||||
return try get(key)?.data
|
return try get(key, loadOriginal: false)?.data
|
||||||
}
|
}
|
||||||
|
|
||||||
func set(_ key: String, data: Data) throws {
|
func set(_ key: String, data: Data, image: UIImage?) throws {
|
||||||
guard let image = scaleImageIfDesired(data: data) else { return }
|
guard let image = scaleImageIfDesired(data: data) ?? image else { return }
|
||||||
|
|
||||||
let entry = Entry(data: storeOriginalDataInMemory ? data : nil, image: image)
|
let entry = Entry(data: storeOriginalDataInMemory ? data : nil, image: image)
|
||||||
memory.setObject(entry, forKey: key)
|
memory.setObject(entry, forKey: key)
|
||||||
|
@ -80,7 +81,7 @@ class ImageDataCache {
|
||||||
private func scaleImageIfDesired(data: Data) -> UIImage? {
|
private func scaleImageIfDesired(data: Data) -> UIImage? {
|
||||||
guard let desiredPixelSize = desiredPixelSize,
|
guard let desiredPixelSize = desiredPixelSize,
|
||||||
let source = CGImageSourceCreateWithData(data as CFData, [kCGImageSourceShouldCache: false] as CFDictionary) else {
|
let source = CGImageSourceCreateWithData(data as CFData, [kCGImageSourceShouldCache: false] as CFDictionary) else {
|
||||||
return UIImage(data: data)
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
let maxDimension = max(desiredPixelSize.width, desiredPixelSize.height)
|
let maxDimension = max(desiredPixelSize.width, desiredPixelSize.height)
|
||||||
|
@ -94,7 +95,7 @@ class ImageDataCache {
|
||||||
if let downsampled = CGImageSourceCreateThumbnailAtIndex(source, 0, downsampleOptions) {
|
if let downsampled = CGImageSourceCreateThumbnailAtIndex(source, 0, downsampleOptions) {
|
||||||
return UIImage(cgImage: downsampled)
|
return UIImage(cgImage: downsampled)
|
||||||
} else {
|
} else {
|
||||||
return UIImage(data: data)
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,14 +85,15 @@ class LoadingLargeImageViewController: UIViewController, LargeImageAnimatableVie
|
||||||
overrideUserInterfaceStyle = .dark
|
overrideUserInterfaceStyle = .dark
|
||||||
view.backgroundColor = .black
|
view.backgroundColor = .black
|
||||||
|
|
||||||
if let entry = cache.get(url) {
|
// always load full resolution from disk for large image, in case the cache is scaled
|
||||||
|
if let entry = cache.get(url, loadOriginal: true) {
|
||||||
createLargeImage(data: entry.data, image: entry.image, url: url)
|
createLargeImage(data: entry.data, image: entry.image, url: url)
|
||||||
} else {
|
} else {
|
||||||
createPreview()
|
createPreview()
|
||||||
|
|
||||||
loadingVC = LoadingViewController()
|
loadingVC = LoadingViewController()
|
||||||
embedChild(loadingVC!)
|
embedChild(loadingVC!)
|
||||||
imageRequest = cache.get(url) { [weak self] (data, image) in
|
imageRequest = cache.get(url, loadOriginal: true) { [weak self] (data, image) in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
self.imageRequest = nil
|
self.imageRequest = nil
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
|
|
@ -191,16 +191,15 @@ class ProfileHeaderView: UIView {
|
||||||
|
|
||||||
let accountID = account.id
|
let accountID = account.id
|
||||||
let avatarURL = account.avatar
|
let avatarURL = account.avatar
|
||||||
avatarRequest = ImageCache.avatars.get(avatarURL) { [weak self] (_, image) in
|
// always load original for avatars, because ImageCache.avatars stores them scaled-down in memory
|
||||||
guard let self = self, let image = image, self.accountID == accountID else { return }
|
avatarRequest = ImageCache.avatars.get(avatarURL, loadOriginal: true) { [weak self] (_, image) in
|
||||||
self.avatarRequest = nil
|
guard let self = self,
|
||||||
|
let image = image,
|
||||||
let transformedImage: UIImage?
|
self.accountID == accountID,
|
||||||
if self.isGrayscale {
|
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else {
|
||||||
transformedImage = ImageGrayscalifier.convert(url: avatarURL, cgImage: image.cgImage!)
|
return
|
||||||
} else {
|
|
||||||
transformedImage = image
|
|
||||||
}
|
}
|
||||||
|
self.avatarRequest = nil
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.avatarImageView.image = transformedImage
|
self.avatarImageView.image = transformedImage
|
||||||
|
@ -208,15 +207,13 @@ class ProfileHeaderView: UIView {
|
||||||
}
|
}
|
||||||
if let header = account.header {
|
if let header = account.header {
|
||||||
headerRequest = ImageCache.headers.get(header) { [weak self] (_, image) in
|
headerRequest = ImageCache.headers.get(header) { [weak self] (_, image) in
|
||||||
guard let self = self, let image = image, self.accountID == accountID else { return }
|
guard let self = self,
|
||||||
self.headerRequest = nil
|
let image = image,
|
||||||
|
self.accountID == accountID,
|
||||||
let transformedImage: UIImage?
|
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: header, image: image) else {
|
||||||
if self.isGrayscale {
|
return
|
||||||
transformedImage = ImageGrayscalifier.convert(url: header, cgImage: image.cgImage!)
|
|
||||||
} else {
|
|
||||||
transformedImage = image
|
|
||||||
}
|
}
|
||||||
|
self.headerRequest = nil
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.headerImageView.image = transformedImage
|
self.headerImageView.image = transformedImage
|
||||||
|
|
Loading…
Reference in New Issue