一些UIImage扩展

压缩图片

/// 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.sizelet width_scale: CGFloat = re_size.width / maxSize!.width let height_scale: CGFloat = re_size.height / maxSize!.heightif 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 = https://www.it610.com/article/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 = https://www.it610.com/article/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.sizelet 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.identityswitch 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.. UIImageView.GIFSource? { if let url = URL(string: imagePath) { do { let data = https://www.it610.com/article/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 = 0self.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 = 0for 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 = .centerlet 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 }

    推荐阅读