美文网首页
一些UIImage扩展

一些UIImage扩展

作者: 微凉初夏 | 来源:发表于2018-04-11 18:14 被阅读0次

    压缩图片

    /// compress 这个方法显然还不是最优解(耗时较长,有一瞬间的内存暴涨,存在闪退隐患),还需要优化
    class func compress(_ data: Data, maxSize: CGSize? = CGSize(width: 600, height: 600), maxKB: CGFloat? = 100) -> UIImage? {
        if let image = UIImage(data: data) {
            return compress(image, maxSize: maxSize, maxKB: maxKB)
        }
    
        return nil
    }
    
    class func compress(_ image: UIImage, maxSize: CGSize? = CGSize(width: 600, height: 600), maxKB: CGFloat? = 100) -> UIImage? {
        if let data = image.resizeImage(maxSize: maxSize)?.resizeImageData(maxKB: maxKB) {
            return UIImage(data: data)
        }
        return image
    }
    
    class func compress(_ image: UIImage, maxSize: CGSize? = CGSize(width: 600, height: 600), maxKB: CGFloat? = 100) -> Data? {
        if let data = image.jpegData(compressionQuality: 1.0) {
            if let img = UIImage(data: data, scale: 1.0) {
                return img.resizeImage(maxSize: maxSize)?.resizeImageData(maxKB: maxKB)
            }
        }
        
        return nil
    }
    
    class func compress(onlySize data: Data, maxSize: CGSize? = CGSize(width: 600, height: 600)) -> UIImage? {
        if let image = UIImage(data: data) {
            return image.resizeImage(maxSize: maxSize)
        }
        
        return nil
    }
    
    class func compress(onlyDataSize data: Data, maxKB: CGFloat? = 100) -> UIImage? {
        if let image = UIImage(data: data) {
            if let d = image.resizeImageData(maxKB: maxKB) {
                return UIImage(data: d)
            }else {
                return image
            }
        }
        
        return nil
    }
    
    func resizeImage(maxSize: CGSize? = CGSize(width: 600, height: 600)) -> UIImage? {
        return autoreleasepool { () -> UIImage? in
            var re_size = self.size
            
            let width_scale: CGFloat = re_size.width / maxSize!.width
            let height_scale: CGFloat = re_size.height / maxSize!.height
            
            if width_scale > 1.0 && width_scale > height_scale {
                re_size = CGSize(width: self.size.width / width_scale, height: self.size.height / width_scale)
            }else if height_scale > 1.0 && height_scale > width_scale {
                re_size = CGSize(width: self.size.width / height_scale, height: self.size.height / height_scale)
            }
            
            UIGraphicsBeginImageContextWithOptions(re_size, false, UIScreen.main.scale)
            self.draw(in: CGRect(origin: .zero, size: re_size))
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            
            return newImage
        }
    }
    
    func resizeImageData(maxKB: CGFloat? = 100) -> Data? {
        return autoreleasepool { () -> Data? in
            if let data = self.jpegData(compressionQuality: 1.0) {
                let size = CGFloat(data.count) / 1024.0 / maxKB!
                let rate: CGFloat = (size > 1) ? (1 / (size + 1.0)) : 1.0
                let imageData = self.jpegData(compressionQuality: rate)
                
                print("- resizeImage - jpeg", data, "->", imageData ?? "0", "is main thread:", Thread.current.isMainThread)
                
                return imageData
            }else {
                //print("- resizeImage - can not to jpeg", newImage ?? "no image")
            }
            
            return nil
        }
    }
    
    /// io_compress 这个方法 速度快,内存消耗小,压缩狠(清晰度不够),压缩的方向会有问题,需要调整图片方向
    class func io_compress(_ data: Data, _ orientation: UIImage.Orientation, maxImageSize: CGSize? = nil) -> UIImage? {
        return autoreleasepool { () -> UIImage? in
            if let source = CGImageSourceCreateWithData(data as CFData, nil) {
                let maxSize: CGSize = maxImageSize ?? UIScreen.main.bounds.size
                
                let options: [CFString : Any] = [
                    kCGImageSourceCreateThumbnailFromImageIfAbsent: true,
                    kCGImageSourceThumbnailMaxPixelSize: max(maxSize.width, maxSize.height)
                ]
                
                if let cgImage = CGImageSourceCreateThumbnailAtIndex(source, 0, options as CFDictionary) {
                    let newImage = UIImage(cgImage: cgImage, scale: 1.0, orientation: orientation)
                    return newImage.fixImageOrientation()
                }
            }
            
            return nil
        }
    }
    ///  图片方向矫正
    func fixImageOrientation() -> UIImage {
        if self.imageOrientation == .up {
            return self
        }
        
        let size = self.size
        var transform: CGAffineTransform = CGAffineTransform.identity
        
        switch self.imageOrientation {
        case .left, .leftMirrored:
            transform = transform.translatedBy(x: size.width, y: 0)
            transform = transform.rotated(by: CGFloat.pi / 2)
        case .down, .downMirrored:
            transform = transform.translatedBy(x: size.width, y: size.height)
            transform = transform.rotated(by: CGFloat.pi)
        case .right, .rightMirrored:
            transform = transform.translatedBy(x: 0, y: size.height)
            transform = transform.rotated(by: -CGFloat.pi / 2)
        default:break
        }
        
        switch self.imageOrientation {
        case .upMirrored, .downMirrored:
            transform = transform.translatedBy(x: size.width, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)
        case .leftMirrored, .rightMirrored:
            transform = transform.translatedBy(x: size.height, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)
        default:break
        }
        
        guard let cg_image = self.cgImage else {return self}
        guard let cg_colorSpace = cg_image.colorSpace else {return self}
        
        guard let context = CGContext(data: nil,
                                      width: Int(size.width),
                                      height: Int(size.height),
                                      bitsPerComponent: cg_image.bitsPerComponent,
                                      bytesPerRow: 0,
                                      space: cg_colorSpace,
                                      bitmapInfo: cg_image.bitmapInfo.rawValue) else {return self}
        
        context.concatenate(transform)
        
        switch self.imageOrientation {
        case .left, .leftMirrored, .right, .rightMirrored:
            context.draw(cg_image, in: CGRect(x: 0, y: 0, width: size.height, height: size.width))
        default:
            context.draw(cg_image, in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
        }
        
        guard let cgImg = context.makeImage() else {return self}
        
        return UIImage(cgImage: cgImg)
    }
    

    重设图片大小

    func reSizeImage(_ reSize: CGSize) -> UIImage? {
        //UIGraphicsBeginImageContext(reSize);
        UIGraphicsBeginImageContextWithOptions(reSize,false,UIScreen.main.scale)
        self.draw(in: CGRect(x: 0, y: 0, width: reSize.width, height: reSize.height))
        guard let reSizeImage: UIImage = UIGraphicsGetImageFromCurrentImageContext() else {return nil}
        UIGraphicsEndImageContext()
        return reSizeImage
    }
    

    等比率缩放(依赖于重设图片大小方法)

    func scaleImage(_ scale: CGFloat) -> UIImage? {
        let reSize = CGSize(width: self.size.width * scale, height: self.size.height * scale)
        return reSizeImage(reSize)
    }
    

    裁剪

    func cutImage(_ rect: CGRect) -> UIImage? {
        guard let cgImage = self.cgImage?.cropping(to: rect) else {return nil}
        
        return UIImage(cgImage: cgImage)
    }
    
    func cutImageWidth(_ widthScale: CGFloat) -> UIImage? {
        guard let cgImage = self.cgImage?.cropping(to: CGRect(x: 0, y: 0, width: self.size.width * widthScale, height: self.size.height)) else {return nil}
        
        return UIImage(cgImage: cgImage)
    }
    

    合成

    func composeImageWith(_ image: UIImage) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(self.size,false,UIScreen.main.scale)
        self.draw(in: CGRect(origin: CGPoint.zero, size: self.size))
        image.draw(in: CGRect(origin: CGPoint.zero, size: image.size))
        guard let reSizeImage: UIImage = UIGraphicsGetImageFromCurrentImageContext() else {return nil}
        UIGraphicsEndImageContext()
        
        return reSizeImage
    }
    

    简单渲染

    func apply(_ color: UIColor, _ imageView: UIImageView) -> UIImage? {
        imageView.tintColor = color
        return self.withRenderingMode(.alwaysTemplate)
    }
    

    GIF

    //通过data获取gif source//
    class func getGifSource(_ data: Data) -> UIImageView.GIFSource? {
        if let source = CGImageSourceCreateWithData(data as CFData, nil) {
            var images = [UIImage]()
            var duration: TimeInterval = 0
            for i in 0..<CGImageSourceGetCount(source) {
                if let image = CGImageSourceCreateImageAtIndex(source, i, nil) {
                    images.append(UIImage(cgImage: image))
                }
                if let properties = CGImageSourceCopyPropertiesAtIndex(source, i, nil) as? [CFString: Any], let dic = properties[kCGImagePropertyGIFDictionary] as? [CFString: Any], let time = dic[kCGImagePropertyGIFDelayTime] as? NSNumber {
                    duration += time.doubleValue
                }
            }
            
            return (images, duration)
        }
        
        return nil
    }
    
    //通过图片路径读取gif source(相册获取的imagepath没有权限读取)//
    class func getGifImageSource(_ imagePath: String) -> UIImageView.GIFSource? {
        if let url = URL(string: imagePath) {
            do {
                let data = try Data(contentsOf: url)
                
                return UIImage.getGifSource(data)
            }catch {
                print(error)
            }
        }
        
        return nil
    }
    
    //以下是UIImageView的扩展(用于展示GIF图片)  
    typealias GIFSource = ([UIImage], TimeInterval)
    
    func showGif(_ gifSource: GIFSource?) {
        guard let source = gifSource else {return}
        self.animationImages = source.0
        self.animationDuration = source.1
        self.animationRepeatCount = 0
        
        self.startAnimating()
    }
    

    添加水印

     func waterMark(_ text: String) -> UIImage? {
        let text_width: CGFloat = self.size.width / 3
        var font_size: Int = 10
        var merge: CGFloat = 20
        var standard_w: CGFloat = 0
        
        for i in font_size..<100 {
            let dic = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: CGFloat(i))]
            let size = text.size(withAttributes: dic)
            
            if i == font_size {
                standard_w = size.width
            }
            
            if size.width >= text_width {
                font_size = i
                merge = merge * (size.width / standard_w)
                break
            }
        }
        
        UIGraphicsBeginImageContext(self.size)
        self.draw(in: CGRect(origin: .zero, size: self.size))
        
        let style = NSMutableParagraphStyle()
        style.lineBreakMode = .byWordWrapping
        style.alignment = .center
        
        let attrDic = [
            NSAttributedString.Key.font: UIFont.systemFont(ofSize: CGFloat(font_size)),
            NSAttributedString.Key.foregroundColor: UIColor.darkText,
            NSAttributedString.Key.paragraphStyle: style,
            NSAttributedString.Key.backgroundColor: UIColor(white: 1, alpha: 0.3)
        ]
        
        let text_size = text.size(withAttributes: attrDic)
        let rect = CGRect(x: merge, y: self.size.height - merge - text_size.height, width: text_size.width, height: text_size.height) // 左下角
        
        text.draw(in: rect, withAttributes: attrDic)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return image
    }

    相关文章

      网友评论

          本文标题:一些UIImage扩展

          本文链接:https://www.haomeiwen.com/subject/uzuzhftx.html