From d106296f6317cc4ea884e65b18694d0a886b15ef Mon Sep 17 00:00:00 2001 From: Efthymis Liapatis Date: Wed, 23 Oct 2024 00:57:08 +0300 Subject: [PATCH] Add macOS support for BlurHashEncode --- Swift/BlurHashEncode.swift | 102 ++++++++++++++++++++++++++----------- 1 file changed, 73 insertions(+), 29 deletions(-) diff --git a/Swift/BlurHashEncode.swift b/Swift/BlurHashEncode.swift index 6b361ab7..08770aba 100644 --- a/Swift/BlurHashEncode.swift +++ b/Swift/BlurHashEncode.swift @@ -1,34 +1,27 @@ +#if os(iOS) import UIKit +#elseif os(macOS) +import AppKit +#endif + +protocol BlurHashEncodable { + var cgImage: CGImage? { get } + + func blurHash(numberOfComponents components: (Int, Int)) -> String? +} -extension UIImage { - public func blurHash(numberOfComponents components: (Int, Int)) -> String? { - let pixelWidth = Int(round(size.width * scale)) - let pixelHeight = Int(round(size.height * scale)) - - let context = CGContext( - data: nil, - width: pixelWidth, - height: pixelHeight, - bitsPerComponent: 8, - bytesPerRow: pixelWidth * 4, - space: CGColorSpace(name: CGColorSpace.sRGB)!, - bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue - )! - context.scaleBy(x: scale, y: -scale) - context.translateBy(x: 0, y: -size.height) - - UIGraphicsPushContext(context) - draw(at: .zero) - UIGraphicsPopContext() - - guard let cgImage = context.makeImage(), - let dataProvider = cgImage.dataProvider, - let data = dataProvider.data, - let pixels = CFDataGetBytePtr(data) else { - assertionFailure("Unexpected error!") - return nil - } - +extension BlurHashEncodable { + func blurHash(numberOfComponents components: (Int, Int)) -> String? { + guard + let cgImage, + let dataProvider = cgImage.dataProvider, + let data = dataProvider.data, + let pixels = CFDataGetBytePtr(data) + else { + assertionFailure("Unexpected error!") + return nil + } + let width = cgImage.width let height = cgImage.height let bytesPerRow = cgImage.bytesPerRow @@ -94,6 +87,57 @@ extension UIImage { } } +#if os(iOS) +extension UIImage: BlurHashEncodable { + var cgImage: CGImage? { + let pixelWidth = Int(round(size.width * scale)) + let pixelHeight = Int(round(size.height * scale)) + + let context = CGContext( + data: nil, + width: pixelWidth, + height: pixelHeight, + bitsPerComponent: 8, + bytesPerRow: pixelWidth * 4, + space: CGColorSpace(name: CGColorSpace.sRGB)!, + bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue + )! + context.scaleBy(x: scale, y: -scale) + context.translateBy(x: 0, y: -size.height) + + UIGraphicsPushContext(context) + draw(at: .zero) + UIGraphicsPopContext() + return context.makeImage() + } +} + +#elseif os(macOS) +extension NSImage: BlurHashEncodable { + var cgImage: CGImage? { + let pixelWidth = Int(round(size.width)) + let pixelHeight = Int(round(size.height)) + + let context = CGContext( + data: nil, + width: pixelWidth, + height: pixelHeight, + bitsPerComponent: 8, + bytesPerRow: pixelWidth * 4, + space: CGColorSpace(name: CGColorSpace.sRGB)!, + bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue + )! + + let graphicsContext = NSGraphicsContext(cgContext: context, flipped: true) + NSGraphicsContext.saveGraphicsState() + NSGraphicsContext.current = graphicsContext + draw(at: .zero, from: NSRect(x: 0, y: 0, width: pixelWidth, height: pixelHeight), operation: .sourceOver, fraction: 1.0) + NSGraphicsContext.restoreGraphicsState() + return context.makeImage() + } +} +#endif + private func encodeDC(_ value: (Float, Float, Float)) -> Int { let roundedR = linearTosRGB(value.0) let roundedG = linearTosRGB(value.1)