//
//  UIImage-Extension.swift
//  BaiSiSMApp
//
//  Created by davidhuang on 2022/11/3.
//  Copyright © 2022 www.davidhuang.com. All rights reserved.
//

import UIKit
extension UIImage {
    static func defaultHeadImage() -> UIImage? {
        return UIImage(named: "default-head-image")
    }
    
    //颜色 转换成 图片
    static func from(color: UIColor,
                     rect: CGRect = CGRect(origin: CGPoint.zero ,size: CGSize(width: 4, height: 4))) -> UIImage {
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()
        context!.setFillColor(color.cgColor)
        context!.fill(rect)
        let img = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return img!
    }
    
    
    // 修复图片旋转
    func fixOrientation() -> UIImage {
        if self.imageOrientation == .up {
            return self
        }
        
        var transform = CGAffineTransform.identity
        
        switch self.imageOrientation {
        case .down, .downMirrored:
            transform = transform.translatedBy(x: self.size.width, y: self.size.height)
            transform = transform.rotated(by: .pi)
            break
            
        case .left, .leftMirrored:
            transform = transform.translatedBy(x: self.size.width, y: 0)
            transform = transform.rotated(by: .pi / 2)
            break
            
        case .right, .rightMirrored:
            transform = transform.translatedBy(x: 0, y: self.size.height)
            transform = transform.rotated(by: -.pi / 2)
            break
            
        default:
            break
        }
        
        switch self.imageOrientation {
        case .upMirrored, .downMirrored:
            transform = transform.translatedBy(x: self.size.width, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)
            break
            
        case .leftMirrored, .rightMirrored:
            transform = transform.translatedBy(x: self.size.height, y: 0);
            transform = transform.scaledBy(x: -1, y: 1)
            break
            
        default:
            break
        }
        
        let ctx = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height), bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0, space: self.cgImage!.colorSpace!, bitmapInfo: self.cgImage!.bitmapInfo.rawValue)
        ctx?.concatenate(transform)
        
        switch self.imageOrientation {
        case .left, .leftMirrored, .right, .rightMirrored:
            ctx?.draw(self.cgImage!, in: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(size.height), height: CGFloat(size.width)))
            break
            
        default:
            ctx?.draw(self.cgImage!, in: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(size.width), height: CGFloat(size.height)))
            break
        }
        
        let cgimg: CGImage = (ctx?.makeImage())!
        let img = UIImage(cgImage: cgimg)
        
        return img
    }
}

// MARK: - 图片大小编辑
extension UIImage {
    
    //等比例放大(图片居中,增加边缘透明范围)
    func bs_scaled(toHeight: CGFloat, opaque: Bool = false) -> UIImage? {
        let scale = toHeight / size.height
        let newWidth = size.width * scale
        UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: toHeight), opaque, self.scale)
        draw(in: CGRect(x: (newWidth - size.width)/2, y: (toHeight - size.height)/2, width: size.width, height: size.height))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    }
    
    func withBackground(color: UIColor, opaque: Bool = true) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
        
        guard let ctx = UIGraphicsGetCurrentContext(), let image = cgImage else { return self }
        defer { UIGraphicsEndImageContext() }
        
        let rect = CGRect(origin: .zero, size: size)
        ctx.setFillColor(color.cgColor)
        ctx.fill(rect)
        ctx.concatenate(CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: size.height))
        ctx.draw(image, in: rect)
        
        return UIGraphicsGetImageFromCurrentImageContext() ?? self
    }
    
    //等比例放大(图片居中,增加边缘透明范围)
    func bs_scaled(toWidth: CGFloat, opaque: Bool = false) -> UIImage? {
        let scale = toWidth / size.width
        let newHeight = size.height * scale
        UIGraphicsBeginImageContextWithOptions(CGSize(width: toWidth, height: newHeight), opaque, self.scale)
        draw(in: CGRect(x: (toWidth - size.width)/2, y: (newHeight - size.height)/2, width: size.width, height: size.height))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    }
    
    
    /// 放大画布大小(图片自定义,增加边缘透明范围)
    /// - Parameters:
    ///   - toSize: 需要的画布大小
    ///   - rect: 图片在画布的位置
    ///   - opaque: 不透明/黑色背景
    /// - Returns: 图片
    func bs_canvas(toSize: CGSize, rect: CGRect, opaque: Bool = false) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(CGSize(width: toSize.width, height: toSize.height), opaque, self.scale)
        draw(in: rect)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    }
    
    
    
    /// 直接使用data进行压缩
    /// - Parameter toKb: 指定data最大的体积
    /// - Returns: data
    func compressOriginalImage(_ toKb: Int = 4 * 1024 * 1024) -> Data?{
        var compression: CGFloat = 1
        let minCompression: CGFloat = 0.1
        var imageData = self.jpegData(compressionQuality: compression)
        if imageData!.count < toKb {
            return imageData
        }
        while imageData!.count > toKb, compression > minCompression {
            compression -= 0.1
            imageData = self.jpegData(compressionQuality: compression)
        }
        if imageData!.count > toKb {
            return imageData
        }
        return imageData
    }
    
    
    func imageSize() -> Int {
        // 如果是JPEG格式，可以调整压缩质量来影响文件大小
        if let jpegData = self.jpegData(compressionQuality: 1.0) {
            return jpegData.count
        }
        // 如果是PNG格式
        if let pngData = self.pngData() {
            return pngData.count
        }
        return 0 // 如果转换失败，返回0
    }
}




enum ImageCopmpressSize {
    //压缩到100KB(1024*100字节)以内
    case one
    //压缩到200KB(1024*100字节)以内
    case two
    //压缩到300KB(1024*100字节)以内
    case three
    //压缩到4M(1024*1024*4)
    case four
}


//extension UIImage {
//    func compressImage(size:ImageCopmpressSize) -> Data{
//        switch size {
//        case .one:
//            return compressImage(maxLength: 1024*100)
//        case .two:
//            return compressImage(maxLength: 1024*200)
//        case .three:
//            return compressImage(maxLength: 1024*300)
//        case .four:
//            return compressImage(maxLength: 4 * 1024 * 1024)
//        }
//    }
//    
//    
//    // 图片压缩 byte
//    func compressImage(maxLength: Int) -> Data {
//        // let tempMaxLength: Int = maxLength / 8
//        let tempMaxLength: Int = maxLength
//        var compression: CGFloat = 1
//        guard var data = self.jpegData(compressionQuality: compression), data.count > tempMaxLength else { return self.jpegData(compressionQuality: compression)! }
//        
//        // 压缩大小
//        var max: CGFloat = 1
//        var min: CGFloat = 0
//        for _ in 0..<6 {
//            compression = (max + min) / 2
//            data = self.jpegData(compressionQuality: compression)!
//            if CGFloat(data.count) < CGFloat(tempMaxLength) * 0.9 {
//                min = compression
//            } else if data.count > tempMaxLength {
//                max = compression
//            } else {
//                break
//            }
//        }
//        var resultImage: UIImage = UIImage(data: data)!
//        if data.count < tempMaxLength { return data }
//        
//        // 压缩大小
//        var lastDataLength: Int = 0
//        while data.count > tempMaxLength && data.count != lastDataLength {
//            lastDataLength = data.count
//            let ratio: CGFloat = CGFloat(tempMaxLength) / CGFloat(data.count)
//            print("Ratio =", ratio)
//            let size: CGSize = CGSize(width: Int(resultImage.size.width * sqrt(ratio)),
//                                      height: Int(resultImage.size.height * sqrt(ratio)))
//            UIGraphicsBeginImageContext(size)
//            resultImage.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
//            resultImage = UIGraphicsGetImageFromCurrentImageContext()!
//            UIGraphicsEndImageContext()
//            data = resultImage.jpegData(compressionQuality: compression)!
//        }
//        return data
//    }
//}
