// // UIImage+Extension.swift // Lanu // // Created by OneeChan on 2025/11/16. // import Foundation import Photos extension UIImage { /// 生成线性渐变图片 /// - Parameters: /// - colors: 渐变颜色数组(至少两种) /// - size: 图片尺寸 /// - startPoint: 渐变起点(坐标系:左上角(0,0),右下角(1,1)) /// - endPoint: 渐变终点 /// - Returns: 生成的渐变图片(nil 表示参数无效) static func generateLinearGradientImage( colors: [UIColor], size: CGSize, location: [NSNumber], startPoint: CGPoint = CGPoint(x: 0, y: 0), endPoint: CGPoint = CGPoint(x: 1, y: 0) ) -> UIImage? { // 校验参数有效性 guard colors.count >= 2, size.width > 0, size.height > 0 else { return nil } // 创建渐变图层 let gradientLayer = CAGradientLayer() gradientLayer.frame = CGRect(origin: .zero, size: size) gradientLayer.colors = colors.map { $0.cgColor } // 转换为 CGColor gradientLayer.locations = location gradientLayer.startPoint = startPoint gradientLayer.endPoint = endPoint // 渲染图层为图片 let renderer = UIGraphicsImageRenderer(size: size) return renderer.image { _ in gradientLayer.render(in: UIGraphicsGetCurrentContext()!) } } } enum LNImageCompressType { case none case avatar case photoWall var maxSize: CGSize { switch self { case .none: .zero case .avatar: .init(width: 600, height: 600) case .photoWall: .init(width: 750, height: 1334) } } } extension UIImage { func saveToLibrary(completion: ((Bool, Error?) -> Void)?) { // 步骤1:检查并请求相册权限 PHPhotoLibrary.requestAuthorization { status in DispatchQueue.main.async { // 回调默认在子线程,切回主线程处理UI switch status { case .authorized, .limited: // 授权(含iOS 14+有限授权) // 步骤2:异步保存图片到相册 PHPhotoLibrary.shared().performChanges({ // 创建保存请求 PHAssetChangeRequest.creationRequestForAsset(from: self) }) { success, error in DispatchQueue.main.async { completion?(success, error) } } case .denied, .restricted: // 权限拒绝/受限 let error = NSError(domain: "AlbumError", code: -1, userInfo: [ NSLocalizedDescriptionKey: "相册权限已拒绝,请前往设置开启" ]) completion?(false, error) case .notDetermined: // 理论上不会走到这里(requestAuthorization已触发授权) completion?(false, NSError(domain: "AlbumError", code: -2, userInfo: [ NSLocalizedDescriptionKey: "权限请求未完成" ])) @unknown default: completion?(false, NSError(domain: "AlbumError", code: -3, userInfo: [ NSLocalizedDescriptionKey: "未知权限状态" ])) } } } } func compress(type: LNImageCompressType) -> UIImage? { let maxSize: CGSize = type.maxSize if maxSize == .zero { UIGraphicsBeginImageContext(CGSizeMake(size.width, size.height)); draw(in: .init(origin: .zero, size: size)) let convertToUpImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return convertToUpImage } if size.width <= maxSize.width && size.height <= maxSize.height { return self } let widthRatio = maxSize.width / size.width let heightRatio = maxSize.height / size.height let scaleRatio = min(widthRatio, heightRatio) let newSize = CGSize(width: size.width * scaleRatio, height: size.height * scaleRatio) let renderer = UIGraphicsImageRenderer(size: newSize) let resizedImage = renderer.image { _ in draw(in: CGRect(origin: .zero, size: newSize)) } return resizedImage } }