mastodon-ios/MastodonSDK/Sources/MastodonExtension/UIImage.swift

109 lines
3.9 KiB
Swift

//
// UIImage.swift
// Mastodon
//
// Created by sxiaojian on 2021/3/8.
//
import CoreImage
import CoreImage.CIFilterBuiltins
import UIKit
extension UIImage {
public static func placeholder(
size: CGSize = CGSize(width: 1, height: 1),
color: UIColor,
cornerRadius: CGFloat = 0
) -> UIImage {
let render = UIGraphicsImageRenderer(size: size)
return render.image { (context: UIGraphicsImageRendererContext) in
// set clear fill
context.cgContext.setFillColor(color.cgColor)
let rect = CGRect(origin: .zero, size: size)
// clip corner if needs
if cornerRadius > 0 {
let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath
context.cgContext.addPath(path)
context.cgContext.clip(using: .evenOdd)
}
// set fill
context.fill(rect)
}
}
}
// refs: https://www.hackingwithswift.com/example-code/media/how-to-read-the-average-color-of-a-uiimage-using-ciareaaverage
extension UIImage {
@available(iOS 14.0, *)
public var dominantColor: UIColor? {
guard let inputImage = CIImage(image: self) else { return nil }
let filter = CIFilter.areaAverage()
filter.inputImage = inputImage
filter.extent = inputImage.extent
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)
}
}
extension UIImage {
public var domainLumaCoefficientsStyle: UIUserInterfaceStyle? {
guard let brightness = cgImage?.brightness else { return nil }
return brightness > 100 ? .light : .dark // 0 ~ 255
}
}
extension UIImage {
public func blur(radius: CGFloat) -> UIImage? {
guard let inputImage = CIImage(image: self) else { return nil }
let blurFilter = CIFilter.gaussianBlur()
blurFilter.inputImage = inputImage
blurFilter.radius = Float(radius)
guard let outputImage = blurFilter.outputImage else { return nil }
guard let cgImage = CIContext().createCGImage(outputImage, from: outputImage.extent) else { return nil }
let image = UIImage(cgImage: cgImage, scale: scale, orientation: imageOrientation)
return image
}
}
extension UIImage {
public func withRoundedCorners(radius: CGFloat? = nil) -> UIImage? {
let maxRadius = min(size.width, size.height) / 2
let cornerRadius: CGFloat = {
guard let radius = radius, radius > 0 else { return maxRadius }
return min(radius, maxRadius)
}()
let render = UIGraphicsImageRenderer(size: size)
return render.image { (_: UIGraphicsImageRendererContext) in
let rect = CGRect(origin: .zero, size: size)
UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).addClip()
draw(in: rect)
}
}
}
extension UIImage {
public static func adaptiveUserInterfaceStyleImage(lightImage: UIImage, darkImage: UIImage) -> UIImage {
let imageAsset = UIImageAsset()
imageAsset.register(lightImage, with: UITraitCollection(traitsFrom: [
UITraitCollection(displayScale: 1.0),
UITraitCollection(userInterfaceStyle: .light)
]))
imageAsset.register(darkImage, with: UITraitCollection(traitsFrom: [
UITraitCollection(displayScale: 1.0),
UITraitCollection(userInterfaceStyle: .dark)
]))
return imageAsset.image(with: UITraitCollection.current)
}
}