2020-11-01 18:59:58 +00:00
|
|
|
//
|
|
|
|
// ImageGrayscalifier.swift
|
|
|
|
// Tusker
|
|
|
|
//
|
|
|
|
// Created by Shadowfacts on 10/29/20.
|
|
|
|
// Copyright © 2020 Shadowfacts. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import UIKit
|
|
|
|
|
|
|
|
struct ImageGrayscalifier {
|
2023-05-13 01:40:17 +00:00
|
|
|
static let queue = DispatchQueue(label: "ImageGrayscalifier", qos: .userInitiated)
|
2020-11-01 18:59:58 +00:00
|
|
|
|
|
|
|
private static let context = CIContext()
|
|
|
|
private static let cache = NSCache<NSURL, UIImage>()
|
|
|
|
|
2021-01-16 20:24:15 +00:00
|
|
|
static func convertIfNecessary(url: URL?, image: UIImage) -> UIImage? {
|
|
|
|
if Preferences.shared.grayscaleImages,
|
|
|
|
let source = image.cgImage {
|
2021-11-13 19:52:02 +00:00
|
|
|
// todo: should this return the original image if conversion fails?
|
2021-01-16 20:24:15 +00:00
|
|
|
return convert(url: url, cgImage: source)
|
|
|
|
} else {
|
|
|
|
return image
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-13 01:40:17 +00:00
|
|
|
static func convert(url: URL?, image: UIImage) -> UIImage? {
|
|
|
|
if let url,
|
|
|
|
let cached = cache.object(forKey: url as NSURL) {
|
|
|
|
return cached
|
|
|
|
}
|
|
|
|
guard let cgImage = image.cgImage else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return doConvert(CIImage(cgImage: cgImage), url: url)
|
|
|
|
}
|
|
|
|
|
2020-11-01 18:59:58 +00:00
|
|
|
static func convert(url: URL?, data: Data) -> UIImage? {
|
|
|
|
if let url = url,
|
|
|
|
let cached = cache.object(forKey: url as NSURL) {
|
|
|
|
return cached
|
|
|
|
}
|
|
|
|
|
|
|
|
guard let source = CIImage(data: data) else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return doConvert(source, url: url)
|
|
|
|
}
|
|
|
|
|
|
|
|
static func convert(url: URL?, cgImage: CGImage) -> UIImage? {
|
|
|
|
if let url = url,
|
|
|
|
let cached = cache.object(forKey: url as NSURL) {
|
|
|
|
return cached
|
|
|
|
}
|
|
|
|
|
|
|
|
return doConvert(CIImage(cgImage: cgImage), url: url)
|
|
|
|
}
|
|
|
|
|
|
|
|
private static func doConvert(_ source: CIImage, url: URL?) -> UIImage? {
|
|
|
|
guard let filter = CIFilter(name: "CIColorMonochrome") else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
filter.setValue(source, forKey: "inputImage")
|
|
|
|
filter.setValue(CIColor(red: 0.85, green: 0.85, blue: 0.85), forKey: "inputColor")
|
|
|
|
filter.setValue(1.0, forKey: "inputIntensity")
|
|
|
|
|
|
|
|
guard let output = filter.outputImage,
|
|
|
|
let cgImage = context.createCGImage(output, from: output.extent) else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
let image = UIImage(cgImage: cgImage)
|
|
|
|
|
|
|
|
if let url = url {
|
|
|
|
cache.setObject(image, forKey: url as NSURL)
|
|
|
|
}
|
|
|
|
|
|
|
|
return image
|
|
|
|
}
|
|
|
|
}
|