| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- //
- // 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
- }
- }
|