UIImage+Extension.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. //
  2. // UIImage+Extension.swift
  3. // MuchinfoSignUp
  4. //
  5. // Created by zhongyuan on 2017/4/11.
  6. // Copyright © 2018年 zhongyuan. All rights reserved.
  7. //
  8. import UIKit
  9. // MARK: - 图片拓展类
  10. extension UIImage {
  11. // MARK: - 降低质量
  12. /// 根据指定体积大小来压缩图片的方法
  13. ///
  14. /// - Parameter maxSize: 指定压缩大小
  15. /// - Returns: 压缩后的图片数据
  16. func resetSizeOfImageData(maxSize: Int) -> Data {
  17. //先判断当前质量是否满足要求,不满足再进行压缩
  18. var finallImageData = UIImage.jpegData(self)(compressionQuality: 1.0)
  19. let sizeOrigin = finallImageData?.count
  20. let sizeOriginKB = sizeOrigin! / 1024
  21. if sizeOriginKB <= maxSize {
  22. return finallImageData!
  23. }
  24. //先调整分辨率
  25. var defaultSize = CGSize(width: 1024, height: 1024)
  26. let newImage = self.newSizeImage(size: defaultSize, source_image: self)
  27. finallImageData = UIImage.jpegData(newImage)(compressionQuality: 1.0)
  28. //保存压缩系数
  29. let compressionQualityArr = NSMutableArray()
  30. let avg = CGFloat(1.0/250)
  31. var value = avg
  32. var i = 250
  33. repeat {
  34. i -= 1
  35. value = CGFloat(i)*avg
  36. compressionQualityArr.add(value)
  37. } while i >= 1
  38. /*
  39. 调整大小
  40. 说明:压缩系数数组compressionQualityArr是从大到小存储。
  41. */
  42. //思路:使用二分法搜索
  43. finallImageData = self.halfFuntion(arr: compressionQualityArr.copy() as! [CGFloat], image: newImage, sourceData: finallImageData!, maxSize: maxSize)
  44. //如果还是未能压缩到指定大小,则进行降分辨率
  45. while finallImageData?.count == 0 {
  46. //每次降100分辨率
  47. if defaultSize.width-100 <= 0 || defaultSize.height-100 <= 0 {
  48. break
  49. }
  50. defaultSize = CGSize(width: defaultSize.width-100, height: defaultSize.height-100)
  51. let image = self.newSizeImage(size: defaultSize, source_image: UIImage(data: UIImage.jpegData(newImage)(compressionQuality: compressionQualityArr.lastObject as! CGFloat)!)!)
  52. finallImageData = self.halfFuntion(arr: compressionQualityArr.copy() as! [CGFloat], image: image, sourceData: UIImage.jpegData(image)(compressionQuality: 1.0)!, maxSize: maxSize)
  53. }
  54. return finallImageData!
  55. }
  56. /// 根据指定的分辨率大小来等比率压缩图片的方法
  57. ///
  58. /// - Parameters:
  59. /// - size: 指定大小
  60. /// - source_image: 目标图片数据
  61. /// - Returns: 压缩后的图片数据
  62. func newSizeImage(size: CGSize, source_image: UIImage) -> UIImage {
  63. var newSize = CGSize(width: source_image.size.width, height: source_image.size.height)
  64. let tempHeight = newSize.height / size.height
  65. let tempWidth = newSize.width / size.width
  66. if tempWidth > 1.0 && tempWidth > tempHeight {
  67. newSize = CGSize(width: source_image.size.width / tempWidth, height: source_image.size.height / tempWidth)
  68. } else if tempHeight > 1.0 && tempWidth < tempHeight {
  69. newSize = CGSize(width: source_image.size.width / tempHeight, height: source_image.size.height / tempHeight)
  70. }
  71. UIGraphicsBeginImageContext(newSize)
  72. source_image.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
  73. let newImage = UIGraphicsGetImageFromCurrentImageContext()
  74. UIGraphicsEndImageContext()
  75. return newImage!
  76. }
  77. // MARK: - 二分法
  78. func halfFuntion(arr: [CGFloat], image: UIImage, sourceData finallImageData: Data, maxSize: Int) -> Data? {
  79. var tempFinallImageData = finallImageData
  80. var tempData = Data.init()
  81. var start = 0
  82. var end = arr.count - 1
  83. var index = 0
  84. var difference = Int.max
  85. while start <= end {
  86. index = start + (end - start)/2
  87. tempFinallImageData = UIImage.jpegData(image)(compressionQuality: arr[index])!
  88. let sizeOrigin = tempFinallImageData.count
  89. let sizeOriginKB = sizeOrigin / 1024
  90. if sizeOriginKB > maxSize {
  91. start = index + 1
  92. } else if sizeOriginKB < maxSize {
  93. if maxSize-sizeOriginKB < difference {
  94. difference = maxSize-sizeOriginKB
  95. tempData = tempFinallImageData
  96. }
  97. end = index - 1
  98. } else {
  99. break
  100. }
  101. }
  102. return tempData
  103. }
  104. //图片压缩 1000kb以下的图片控制在100kb-200kb之间
  105. func compressImageSize() -> Data{
  106. var zipImageData = UIImage.jpegData(self)(compressionQuality: 1.0)!//UIImageJPEGRepresentation(self, 1.0)!
  107. let originalImgSize = zipImageData.count/1024 as Int //获取图片大小
  108. if originalImgSize>1500 {
  109. zipImageData = UIImage.jpegData(self)(compressionQuality: 0.2)!//UIImageJPEGRepresentation(self,0.2)!
  110. } else if originalImgSize>600 {
  111. zipImageData = UIImage.jpegData(self)(compressionQuality: 0.4)!//UIImageJPEGRepresentation(self,0.4)!
  112. } else if originalImgSize>400 {
  113. zipImageData = UIImage.jpegData(self)(compressionQuality: 0.6)!//UIImageJPEGRepresentation(self,0.6)!
  114. } else if originalImgSize>300 {
  115. zipImageData = UIImage.jpegData(self)(compressionQuality: 0.7)!//UIImageJPEGRepresentation(self,0.7)!
  116. } else if originalImgSize>200 {
  117. zipImageData = UIImage.jpegData(self)(compressionQuality: 0.8)!//UIImageJPEGRepresentation(self,0.8)!
  118. }
  119. return zipImageData
  120. }
  121. func resizeImage() -> UIImage{
  122. //prepare constants
  123. let width = self.size.width
  124. let height = self.size.height
  125. let scale = width/height
  126. var sizeChange = CGSize()
  127. if width <= 1280 && height <= 1280{ //a,图片宽或者高均小于或等于1280时图片尺寸保持不变,不改变图片大小
  128. return self
  129. } else if width > 1280 || height > 1280 {//b,宽或者高大于1280,但是图片宽度高度比小于或等于2,则将图片宽或者高取大的等比压缩至1280
  130. if scale <= 2 && scale >= 1 {
  131. let changedWidth:CGFloat = 1280
  132. let changedheight:CGFloat = changedWidth / scale
  133. sizeChange = CGSize(width: changedWidth, height: changedheight)
  134. } else if scale >= 0.5 && scale <= 1 {
  135. let changedheight:CGFloat = 1280
  136. let changedWidth:CGFloat = changedheight * scale
  137. sizeChange = CGSize(width: changedWidth, height: changedheight)
  138. } else if width > 1280 && height > 1280 {//宽以及高均大于1280,但是图片宽高比大于2时,则宽或者高取小的等比压缩至1280
  139. if scale > 2 {//高的值比较小
  140. let changedheight:CGFloat = 1280
  141. let changedWidth:CGFloat = changedheight * scale
  142. sizeChange = CGSize(width: changedWidth, height: changedheight)
  143. } else if scale < 0.5{//宽的值比较小
  144. let changedWidth:CGFloat = 1280
  145. let changedheight:CGFloat = changedWidth / scale
  146. sizeChange = CGSize(width: changedWidth, height: changedheight)
  147. }
  148. } else {//d, 宽或者高,只有一个大于1280,并且宽高比超过2,不改变图片大小
  149. return self
  150. }
  151. }
  152. UIGraphicsBeginImageContext(sizeChange)
  153. //draw resized image on Context
  154. self.draw(in: CGRect(origin: CGPoint.zero, size: CGSize(width: sizeChange.width, height: sizeChange.height)))
  155. //create UIImage
  156. let resizedImg = UIGraphicsGetImageFromCurrentImageContext()
  157. UIGraphicsEndImageContext()
  158. return resizedImg!
  159. }
  160. /// 传入图片image回传对应的base64字符串,默认不带有data标识,
  161. func imageToBase64String() -> String? {
  162. /// 根据图片得到对应的二进制编码
  163. guard let imageData = self.pngData() else {
  164. return nil
  165. }
  166. /// 根据二进制编码得到对应的base64字符串
  167. var base64String = imageData.base64EncodedString(options: .endLineWithCarriageReturn)
  168. /// 根据格式拼接数据头 添加header信息,扩展名信息
  169. base64String = "data:image/png;base64," + base64String
  170. return base64String
  171. }
  172. /// 图片旋转
  173. /// - Parameter orientation: 角度
  174. func transRotation(_ orientation: UIImage.Orientation) -> UIImage? {
  175. var rotate: Double = 0.0
  176. var rect: CGRect = CGRect.zero
  177. var translateX: CGFloat = 0.0;
  178. var translateY: CGFloat = 0.0;
  179. var scaleX: CGFloat = 1.0;
  180. var scaleY: CGFloat = 1.0;
  181. switch orientation {
  182. case .left:
  183. rotate = .pi/2
  184. rect = CGRect(x: 0.0, y: 0.0, width: self.size.height, height: self.size.width)
  185. translateX = 0
  186. translateY = -rect.size.width
  187. scaleY = rect.size.width/rect.size.height
  188. scaleX = rect.size.height/rect.size.width
  189. case .right:
  190. rotate = 33 * .pi/2
  191. rect = CGRect(x: 0, y: 0, width: self.size.height, height:self.size.width)
  192. translateX = -rect.size.height
  193. translateY = 0
  194. scaleY = rect.size.width/rect.size.height
  195. scaleX = rect.size.height/rect.size.width
  196. case .down:
  197. rotate = .pi
  198. rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
  199. translateX = -rect.size.width
  200. translateY = -rect.size.height
  201. default:
  202. rotate = 0.0
  203. rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
  204. translateX = 0
  205. translateY = 0
  206. }
  207. UIGraphicsBeginImageContext(rect.size);
  208. let context = UIGraphicsGetCurrentContext()
  209. /// 做CTM变换
  210. context!.translateBy(x: 0.0, y: rect.size.height)
  211. context!.scaleBy(x: 1.0, y: -1.0)
  212. context!.rotate(by: CGFloat(rotate))
  213. context!.translateBy(x: translateX, y: translateY)
  214. context!.scaleBy(x: scaleX, y: scaleY)
  215. /// 绘制图片
  216. context?.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: rect.size.width, height: rect.size.height))
  217. return UIGraphicsGetImageFromCurrentImageContext()
  218. }
  219. /// 按照尺寸大小压缩图片
  220. /// - Parameter size: size
  221. func reSizeImage(_ size: CGSize)-> UIImage {
  222. UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale);
  223. self.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height));
  224. let image: UIImage = UIGraphicsGetImageFromCurrentImageContext() ?? UIImage();
  225. UIGraphicsEndImageContext();
  226. return image;
  227. }
  228. static func image(_ color: UIColor, _ size: CGSize) -> UIImage {
  229. let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
  230. UIGraphicsBeginImageContext(rect.size )
  231. let context = UIGraphicsGetCurrentContext()
  232. context?.setFillColor(color.cgColor)
  233. context?.fill(rect)
  234. guard let image = UIGraphicsGetImageFromCurrentImageContext() else { return UIImage() }
  235. UIGraphicsEndImageContext()
  236. return image
  237. }
  238. }