UIImage+Category.swift 14.7 KB
//
//  UIImage+Category.swift
//  UniKar
//
//  Created by pxh on 2016/12/6.
//  Copyright © 2016年 pxh. All rights reserved.
//

import UIKit
import MBProgressHUD
import Photos
import Charts
import MobileCoreServices


extension UIImage {
    
    //    func accessCameraAuthority() -> Bool
    //    {
    //        let authStatus = AVCaptureDevice.authorizationStatus(for: .video)
    //        if authStatus == .restricted || authStatus == .denied {
    //            MBProgressHUD.show("请在iPhone的 设置-隐私-相机 中允许访问相机")
    //        } else if PHPhotoLibrary.authorizationStatus().rawValue == 2 {
    //            MBProgressHUD.show("请在iPhone的 设置-隐私-相册 中允许访问相册")
    //        } else {
    //
    //        }
    //    }
    func saveImageToPath(_ name: String, path: String? = nil) -> Bool {
        if let imageData = self.pngData() {
            let imagePath = self.imagePath(path) + "\(name).png"
            
            do {
                try imageData.write(to: URL(fileURLWithPath: imagePath), options: .atomic)
            } catch {
                return false
            }
            return true
        } else {
            return false
        }
    }
    
    class func getImageFromPath(_ name: String, path: String? = nil)-> UIImage? {
        if path == nil {
            if let image = UIImage(contentsOfFile: NSHomeDirectory() + "/Documents/images/\(name).png") {
                return image
            } else {
                return nil
            }
        } else {
            if let image = UIImage(contentsOfFile: NSHomeDirectory() + "/Documents/images/\(path!)/\(name).png") {
                return image
            } else {
                return nil
            }
        }
    }
    
    class func getImagesName(path: String) -> [String] {
        let manager = FileManager.default
        var imageArray: [String] = []
        if let contentsOfURL = try? manager.contentsOfDirectory(at: URL(fileURLWithPath: NSHomeDirectory() + "/Documents/images/\(path)/"), includingPropertiesForKeys: nil, options: .skipsHiddenFiles) {
            for url in contentsOfURL {
                if url.lastPathComponent.hasSuffix(".png") {
                    imageArray.append(url.lastPathComponent.replacingOccurrences(of: ".png", with: ""))
                }
            }
        }
        return imageArray
    }
    
    class func deleteImage(name: String, path: String) -> Bool {
        let manager = FileManager.default
        do {
            try manager.removeItem(at: URL(fileURLWithPath: NSHomeDirectory() + "/Documents/images/\(path)/\(name).png"))
            return true
        } catch {
            return false
        }
    }
    
    private func imagePath(_ path: String? = nil) -> String {
        var newPath = NSHomeDirectory() + "/Documents/images/"
        if path != nil {
            newPath += "\(path!)/"
        }
        if !FileManager.default.fileExists(atPath: newPath) {
            print(newPath)
            try! FileManager.default.createDirectory(atPath: newPath, withIntermediateDirectories: true, attributes: nil)
        }
        return newPath
    }
    
    
    //    private func getDocumentsDirectory() -> URL {
    //        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    //
    //        return paths[0]
    //    }
    
    
    
    func saveImageToPhotoLibrary() {
        
        let img = self
        
        // 判断权限
        switch PHPhotoLibrary.authorizationStatus() {
        case .authorized:
            saveImage(image: img)
        case .notDetermined:
            PHPhotoLibrary.requestAuthorization { [weak self](status) in
                if status == .authorized {
                    self?.saveImage(image: img)
                } else {
                    print("User denied")
                }
            }
            
        case .restricted, .denied:
            MBProgressHUD.showh("请开启允许访问相册权限")
            //            if let url = URL.init(string: UIApplication.openSettingsURLString) {
            //                if UIApplication.shared.canOpenURL(url) {
            //                    UIApplication.shared.openURL(url)
            //                }
            //            }
        default:
            break
            
        }
    }
    
    private func saveImage(image: UIImage) {
        PHPhotoLibrary.shared().performChanges({
            PHAssetChangeRequest.creationRequestForAsset(from: image)
        }, completionHandler: { (isSuccess, error) in
            DispatchQueue.main.async {
                if isSuccess {// 成功
                    MBProgressHUD.showh("已保存到系统相册")
                }
            }
        })
    }
    
    
    
    
    //压缩图片  10k
    func compressOriginalImage(_ maxSizeKbytes: CGFloat) -> UIImage? {
        
        
        var imageData = UIImage.jpegData(self)(compressionQuality: 1.0)
        var dataKBytes = CGFloat((imageData?.count)!)/1000.0
        var maxQuality: CGFloat = 0.9
        var lastData = dataKBytes
        while dataKBytes > maxSizeKbytes && maxQuality > 0.01 {
            print("压缩图片!")
            maxQuality -= 0.01
            imageData = UIImage.jpegData(self)(compressionQuality: maxQuality)//UIImageJPEGRepresentation(self, maxQuality)
            dataKBytes = CGFloat((imageData?.count)!)/1000.0
            if lastData == dataKBytes {
                break
            } else {
                lastData = dataKBytes
            }
        }
        return UIImage.init(data: imageData!)
    }
    
    class func getImageWithColor(_ color : UIColor , rect : CGRect)->UIImage{
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()
        context!.setFillColor(color.cgColor)
        let fillRect = CGRect.init(origin: CGPoint.zero, size: rect.size)
        context!.fill(fillRect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
    
    class func maskImageWithMaskrect(maskRect:CGRect,clearRect:CGRect) -> UIImage {
        UIGraphicsBeginImageContext(maskRect.size)
        let ctx = UIGraphicsGetCurrentContext()
        ctx?.setFillColor(UIColor.black.cgColor)
        ctx?.setFillColor(red: 0, green: 0, blue: 0, alpha: 0.6)
        ctx?.fill(maskRect)
        ctx?.clear(clearRect)
        
        let img = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return img!
    }
    
    
    
    
    //黑白效果滤镜
    func noir() -> UIImage?
    {
        let imageData = self.pngData()
        let inputImage = CoreImage.CIImage(data: imageData!)
        let context = CIContext(options:nil)
        let filter = CIFilter(name:"CIPhotoEffectNoir")
        filter!.setValue(inputImage, forKey: kCIInputImageKey)
        if let outputImage = filter!.outputImage {
            //            let outImage = context.createCGImage(outputImage, fromRect: outputImage.extent)
            let outImage = context.createCGImage(outputImage, from: outputImage.extent)
            //            return UIImage(CGImage: outImage!)
            return UIImage.init(cgImage: outImage!)
        }
        return nil
    }
    
    
    //棕褐色复古滤镜(老照片效果)
    func sepiaTone() -> UIImage?
    {
        let imageData = self.pngData()
        let inputImage = CoreImage.CIImage(data: imageData!)
        let context = CIContext(options:nil)
        let filter = CIFilter(name:"CISepiaTone")
        filter!.setValue(inputImage, forKey: kCIInputImageKey)
        filter!.setValue(0.8, forKey: "inputIntensity")
        if let outputImage = filter!.outputImage {
            //            let outImage = context.createCGImage(outputImage, fromRect: outputImage.extent)
            //            return UIImage(CGImage: outImage)
            let outImage = context.createCGImage(outputImage, from: outputImage.extent)
            return UIImage.init(cgImage: outImage!)
        }
        return nil
    }
    
    //将string转化为二维码
    class func createQRForString(qrString: String?, qrImageName: String?) -> UIImage?{
        if let sureQRString = qrString{
            let stringData = sureQRString.data(using: String.Encoding.utf8, allowLossyConversion: false)
            //创建一个二维码的滤镜
            let qrFilter = CIFilter(name: "CIQRCodeGenerator")
            qrFilter?.setValue(stringData, forKey: "inputMessage")
            qrFilter?.setValue("H", forKey: "inputCorrectionLevel")
            let qrCIImage = qrFilter?.outputImage
            
            // 创建一个颜色滤镜,黑白色
            let colorFilter = CIFilter(name: "CIFalseColor")!
            colorFilter.setDefaults()
            colorFilter.setValue(qrCIImage, forKey: "inputImage")
            colorFilter.setValue(CIColor(red: 0, green: 0, blue: 0), forKey: "inputColor0")
            colorFilter.setValue(CIColor(red: 1, green: 1, blue: 1), forKey: "inputColor1")
            // 返回二维码image
            let codeImage = UIImage(ciImage: (colorFilter.outputImage!.transformed(by: CGAffineTransform(scaleX: 5, y: 5))))
            
            // 中间一般放logo
            if let iconImage = UIImage(named: qrImageName!) {
                let rect = CGRect(x: 0, y: 0, width: codeImage.size.width, height: codeImage.size.height)
                
                UIGraphicsBeginImageContext(rect.size)
                codeImage.draw(in: rect)
                let avatarSize = CGSize(width: rect.size.width*0.25, height: rect.size.height*0.25)
                
                let x = (rect.width - avatarSize.width) * 0.5
                let y = (rect.height - avatarSize.height) * 0.5
                iconImage.draw(in: CGRect(x: x, y: y, width: avatarSize.width, height: avatarSize.height))
                
                let resultImage = UIGraphicsGetImageFromCurrentImageContext()
                
                UIGraphicsEndImageContext()
                return resultImage
            }
            return codeImage
        }
        return nil
    }
}

extension UIImage {
    
    func toJpegData (compressionQuality: CGFloat, hasAlpha: Bool = true, orientation: Int = 6) -> Data? {
        guard cgImage != nil else { return nil }
        let options: NSDictionary =     [
            kCGImagePropertyOrientation: orientation,
            kCGImagePropertyHasAlpha: hasAlpha,
            kCGImageDestinationLossyCompressionQuality: compressionQuality
        ]
        return toData(options: options, type: .jpeg)
    }
    
    func toData (options: NSDictionary, type: ImageType) -> Data? {
        guard cgImage != nil else { return nil }
        return toData(options: options, type: type.value)
    }
    
    // about properties: https://developer.apple.com/documentation/imageio/1464962-cgimagedestinationaddimage
    func toData (options: NSDictionary, type: CFString) -> Data? {
        guard let cgImage = cgImage else { return nil }
        return autoreleasepool { () -> Data? in
            let data = NSMutableData()
            guard let imageDestination = CGImageDestinationCreateWithData(data as CFMutableData, type, 1, nil) else { return nil }
            CGImageDestinationAddImage(imageDestination, cgImage, options)
            CGImageDestinationFinalize(imageDestination)
            return data as Data
        }
    }
    
    // https://developer.apple.com/documentation/mobilecoreservices/uttype/uti_image_content_types
    enum ImageType {
        case image // abstract image data
        case jpeg                       // JPEG image
        case jpeg2000                   // JPEG-2000 image
        case tiff                       // TIFF image
        case pict                       // Quickdraw PICT format
        case gif                        // GIF image
        case png                        // PNG image
        case quickTimeImage             // QuickTime image format (OSType 'qtif')
        case appleICNS                  // Apple icon data
        case bmp                        // Windows bitmap
        case ico                        // Windows icon data
        case rawImage                   // base type for raw image data (.raw)
        case scalableVectorGraphics     // SVG image
        case livePhoto                  // Live Photo
        
        var value: CFString {
            switch self {
            case .image: return kUTTypeImage
            case .jpeg: return kUTTypeJPEG
            case .jpeg2000: return kUTTypeJPEG2000
            case .tiff: return kUTTypeTIFF
            case .pict: return kUTTypePICT
            case .gif: return kUTTypeGIF
            case .png: return kUTTypePNG
            case .quickTimeImage: return kUTTypeQuickTimeImage
            case .appleICNS: return kUTTypeAppleICNS
            case .bmp: return kUTTypeBMP
            case .ico: return kUTTypeICO
            case .rawImage: return kUTTypeRawImage
            case .scalableVectorGraphics: return kUTTypeScalableVectorGraphics
            case .livePhoto: if #available(iOS 9.1, *) {
                return kUTTypeLivePhoto
            } else {
                return kUTTypeRawImage
                // Fallback on earlier versions
            }
            }
        }
    }
    func rbg565Data() -> Data? {
        
        guard let cgImage = self.cgImage
                
        else { return Data() }
        
        let width = Int(size.width)
        
        let height = Int(size.height)
        
        // bytes array
        
        let srcRowBytes = 4 * width
        
        var bytes = Array<UInt32>.init(repeating: 0, count: srcRowBytes * height)
        
        // create context for image
        
        guard let context = CGContext(data: &bytes, width: width, height: height, bitsPerComponent: 8, bytesPerRow: srcRowBytes, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue )
                
        else { return nil }
        
        // fill buffer
        
        context.interpolationQuality = .high
        
        context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))
        
        var newBytes = [UInt8]()
        
        for col in 0..<height {
            for row in 0..<width {
                //                let pixeIndex = (col*width+row)*4
                let color = bytes[(col*width+row)]
                let r = UInt8(( color >> 0 ) & 0xff )
                let g = UInt8(( color >> 8 ) & 0xff )
                let b = UInt8(( color >> 16) & 0xff )
                let data = (r & 0xf8) | ((g >> 5) & 0x7)
                newBytes.append(data)
                let data2 = ((g<<3) & 0xE0) | ((b >> 3) & 0x1F)
                newBytes.append(data2)
            }
        }
        return Data(bytes: newBytes, count: newBytes.count)
    }
}