Advertisement
Guest User

Untitled

a guest
May 26th, 2015
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.48 KB | None | 0 0
  1. import Accelerate
  2. import UIKit
  3.  
  4. public extension UIImage {
  5. public func applyLightEffect() -> UIImage? {
  6. return applyBlur(radius: 30, tintColor: UIColor(white: 1, alpha: 0.3))
  7. }
  8.  
  9. public func applyExtraLightEffect() -> UIImage? {
  10. return applyBlur(radius: 20, tintColor: UIColor(white: 0.97, alpha: 0.82))
  11. }
  12.  
  13. public func applyDarkEffect() -> UIImage? {
  14. return applyBlur(radius: 20, tintColor: UIColor(white: 0.11, alpha: 0.73))
  15. }
  16.  
  17. public func applyTintEffect(color tintColor: UIColor) -> UIImage? {
  18. return applyBlur(radius: 10, tintColor: tintColor.colorWithAlphaComponent(0.6), saturationDeltaFactor: -1)
  19. }
  20.  
  21. public func applyBlur(radius blurRadius: CGFloat, tintColor: UIColor? = nil, saturationDeltaFactor: CGFloat = 1.8, maskImage: UIImage? = nil) -> UIImage? {
  22. if size.width < 1 || size.height < 1 {
  23. println(String(format: "*** error: invalid size: %.2f x %.2f. Both dimensions must be >= 1: \(self)", size.width, size.height))
  24. return nil
  25. }
  26.  
  27. if CGImage == nil {
  28. println("*** error: image must be backed by a CGImage: \(self)")
  29. return nil
  30. }
  31.  
  32. if let maskImage = maskImage where maskImage.CGImage == nil {
  33. println("*** error: maskImage must be backed by a CGImage: \(maskImage)")
  34. return nil
  35. }
  36.  
  37. let imageRect = CGRect(origin: CGPointZero, size: size)
  38. var effectImage = self
  39.  
  40. let hasBlur = Float(blurRadius) > FLT_EPSILON
  41. let hasSaturationChange = Float(abs(saturationDeltaFactor - 1)) > FLT_EPSILON
  42.  
  43. if hasBlur || hasSaturationChange {
  44. UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale)
  45. let effectInContext = UIGraphicsGetCurrentContext()
  46. CGContextScaleCTM(effectInContext, 1, -1)
  47. CGContextTranslateCTM(effectInContext, 0, -size.height)
  48. CGContextDrawImage(effectInContext, imageRect, CGImage)
  49. var effectInBuffer = vImage_Buffer(data: CGBitmapContextGetData(effectInContext), height: UInt(CGBitmapContextGetHeight(effectInContext)), width: UInt(CGBitmapContextGetWidth(effectInContext)), rowBytes: CGBitmapContextGetBytesPerRow(effectInContext))
  50.  
  51. UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale)
  52. let effectOutContext = UIGraphicsGetCurrentContext()
  53. var effectOutBuffer = vImage_Buffer(data: CGBitmapContextGetData(effectOutContext), height: UInt(CGBitmapContextGetHeight(effectOutContext)), width: UInt(CGBitmapContextGetWidth(effectOutContext)), rowBytes: CGBitmapContextGetBytesPerRow(effectOutContext))
  54.  
  55. if hasBlur {
  56. let inputRadius = blurRadius * UIScreen.mainScreen().scale
  57. var radius = UInt32(floor(inputRadius * 3.0 * CGFloat(sqrt(2 * M_PI)) / 4 + 0.5))
  58. if radius % 2 != 1 {
  59. ++radius // force radius to be odd so that the three box-blur methodology works.
  60. }
  61.  
  62. let imageEdgeExtendFlags = vImage_Flags(kvImageEdgeExtend)
  63. vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, nil, 0, 0, radius, radius, nil, imageEdgeExtendFlags)
  64. vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, nil, 0, 0, radius, radius, nil, imageEdgeExtendFlags)
  65. vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, nil, 0, 0, radius, radius, nil, imageEdgeExtendFlags)
  66. }
  67.  
  68. var effectImageBuffersAreSwapped = false
  69. if hasSaturationChange {
  70. let s = saturationDeltaFactor
  71. let floatingPointSaturationMatrix = [
  72. 0.0722 + 0.9278 * s, 0.0722 - 0.0722 * s, 0.0722 - 0.0722 * s, 0,
  73. 0.7152 - 0.7152 * s, 0.7152 + 0.2848 * s, 0.7152 - 0.7152 * s, 0,
  74. 0.2126 - 0.2126 * s, 0.2126 - 0.2126 * s, 0.2126 + 0.7873 * s, 0,
  75. 0, 0, 0, 1
  76. ]
  77.  
  78. let divisor: CGFloat = 256
  79. let matrixSize = count(floatingPointSaturationMatrix)
  80. let saturationMatrix = map(floatingPointSaturationMatrix) {
  81. return Int16(round($0 * divisor))
  82. }
  83.  
  84. if hasBlur {
  85. vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, Int32(divisor), nil, nil, vImage_Flags(kvImageNoFlags))
  86. effectImageBuffersAreSwapped = true
  87. } else {
  88. vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, Int32(divisor), nil, nil, vImage_Flags(kvImageNoFlags))
  89. }
  90. }
  91.  
  92. if !effectImageBuffersAreSwapped {
  93. effectImage = UIGraphicsGetImageFromCurrentImageContext()
  94. }
  95. UIGraphicsEndImageContext()
  96.  
  97. if effectImageBuffersAreSwapped {
  98. effectImage = UIGraphicsGetImageFromCurrentImageContext()
  99. }
  100. UIGraphicsEndImageContext()
  101. }
  102.  
  103. // Set up output context.
  104. UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale)
  105. let outputContext = UIGraphicsGetCurrentContext()
  106. CGContextScaleCTM(outputContext, 1, -1)
  107. CGContextTranslateCTM(outputContext, 0, -size.height)
  108.  
  109. // Draw base image.
  110. CGContextDrawImage(outputContext, imageRect, CGImage)
  111.  
  112. // Draw effect image.
  113. if hasBlur {
  114. CGContextSaveGState(outputContext)
  115. if let image = maskImage {
  116. CGContextClipToMask(outputContext, imageRect, image.CGImage)
  117. }
  118. CGContextDrawImage(outputContext, imageRect, effectImage.CGImage)
  119. CGContextRestoreGState(outputContext)
  120. }
  121.  
  122. // Add in color tint.
  123. if let tintColor = tintColor {
  124. CGContextSaveGState(outputContext)
  125. CGContextSetFillColorWithColor(outputContext, tintColor.CGColor)
  126. CGContextFillRect(outputContext, imageRect)
  127. CGContextRestoreGState(outputContext)
  128. }
  129.  
  130. // Output image is ready.
  131. let outputImage = UIGraphicsGetImageFromCurrentImageContext()
  132. UIGraphicsEndImageContext()
  133.  
  134. return outputImage
  135. }
  136. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement