Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Accelerate
- import UIKit
- public extension UIImage {
- public func applyLightEffect() -> UIImage? {
- return applyBlur(radius: 30, tintColor: UIColor(white: 1, alpha: 0.3))
- }
- public func applyExtraLightEffect() -> UIImage? {
- return applyBlur(radius: 20, tintColor: UIColor(white: 0.97, alpha: 0.82))
- }
- public func applyDarkEffect() -> UIImage? {
- return applyBlur(radius: 20, tintColor: UIColor(white: 0.11, alpha: 0.73))
- }
- public func applyTintEffect(color tintColor: UIColor) -> UIImage? {
- return applyBlur(radius: 10, tintColor: tintColor.colorWithAlphaComponent(0.6), saturationDeltaFactor: -1)
- }
- public func applyBlur(radius blurRadius: CGFloat, tintColor: UIColor? = nil, saturationDeltaFactor: CGFloat = 1.8, maskImage: UIImage? = nil) -> UIImage? {
- if size.width < 1 || size.height < 1 {
- println(String(format: "*** error: invalid size: %.2f x %.2f. Both dimensions must be >= 1: \(self)", size.width, size.height))
- return nil
- }
- if CGImage == nil {
- println("*** error: image must be backed by a CGImage: \(self)")
- return nil
- }
- if let maskImage = maskImage where maskImage.CGImage == nil {
- println("*** error: maskImage must be backed by a CGImage: \(maskImage)")
- return nil
- }
- let imageRect = CGRect(origin: CGPointZero, size: size)
- var effectImage = self
- let hasBlur = Float(blurRadius) > FLT_EPSILON
- let hasSaturationChange = Float(abs(saturationDeltaFactor - 1)) > FLT_EPSILON
- if hasBlur || hasSaturationChange {
- UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale)
- let effectInContext = UIGraphicsGetCurrentContext()
- CGContextScaleCTM(effectInContext, 1, -1)
- CGContextTranslateCTM(effectInContext, 0, -size.height)
- CGContextDrawImage(effectInContext, imageRect, CGImage)
- var effectInBuffer = vImage_Buffer(data: CGBitmapContextGetData(effectInContext), height: UInt(CGBitmapContextGetHeight(effectInContext)), width: UInt(CGBitmapContextGetWidth(effectInContext)), rowBytes: CGBitmapContextGetBytesPerRow(effectInContext))
- UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale)
- let effectOutContext = UIGraphicsGetCurrentContext()
- var effectOutBuffer = vImage_Buffer(data: CGBitmapContextGetData(effectOutContext), height: UInt(CGBitmapContextGetHeight(effectOutContext)), width: UInt(CGBitmapContextGetWidth(effectOutContext)), rowBytes: CGBitmapContextGetBytesPerRow(effectOutContext))
- if hasBlur {
- let inputRadius = blurRadius * UIScreen.mainScreen().scale
- var radius = UInt32(floor(inputRadius * 3.0 * CGFloat(sqrt(2 * M_PI)) / 4 + 0.5))
- if radius % 2 != 1 {
- ++radius // force radius to be odd so that the three box-blur methodology works.
- }
- let imageEdgeExtendFlags = vImage_Flags(kvImageEdgeExtend)
- vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, nil, 0, 0, radius, radius, nil, imageEdgeExtendFlags)
- vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, nil, 0, 0, radius, radius, nil, imageEdgeExtendFlags)
- vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, nil, 0, 0, radius, radius, nil, imageEdgeExtendFlags)
- }
- var effectImageBuffersAreSwapped = false
- if hasSaturationChange {
- let s = saturationDeltaFactor
- let floatingPointSaturationMatrix = [
- 0.0722 + 0.9278 * s, 0.0722 - 0.0722 * s, 0.0722 - 0.0722 * s, 0,
- 0.7152 - 0.7152 * s, 0.7152 + 0.2848 * s, 0.7152 - 0.7152 * s, 0,
- 0.2126 - 0.2126 * s, 0.2126 - 0.2126 * s, 0.2126 + 0.7873 * s, 0,
- 0, 0, 0, 1
- ]
- let divisor: CGFloat = 256
- let matrixSize = count(floatingPointSaturationMatrix)
- let saturationMatrix = map(floatingPointSaturationMatrix) {
- return Int16(round($0 * divisor))
- }
- if hasBlur {
- vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, Int32(divisor), nil, nil, vImage_Flags(kvImageNoFlags))
- effectImageBuffersAreSwapped = true
- } else {
- vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, Int32(divisor), nil, nil, vImage_Flags(kvImageNoFlags))
- }
- }
- if !effectImageBuffersAreSwapped {
- effectImage = UIGraphicsGetImageFromCurrentImageContext()
- }
- UIGraphicsEndImageContext()
- if effectImageBuffersAreSwapped {
- effectImage = UIGraphicsGetImageFromCurrentImageContext()
- }
- UIGraphicsEndImageContext()
- }
- // Set up output context.
- UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.mainScreen().scale)
- let outputContext = UIGraphicsGetCurrentContext()
- CGContextScaleCTM(outputContext, 1, -1)
- CGContextTranslateCTM(outputContext, 0, -size.height)
- // Draw base image.
- CGContextDrawImage(outputContext, imageRect, CGImage)
- // Draw effect image.
- if hasBlur {
- CGContextSaveGState(outputContext)
- if let image = maskImage {
- CGContextClipToMask(outputContext, imageRect, image.CGImage)
- }
- CGContextDrawImage(outputContext, imageRect, effectImage.CGImage)
- CGContextRestoreGState(outputContext)
- }
- // Add in color tint.
- if let tintColor = tintColor {
- CGContextSaveGState(outputContext)
- CGContextSetFillColorWithColor(outputContext, tintColor.CGColor)
- CGContextFillRect(outputContext, imageRect)
- CGContextRestoreGState(outputContext)
- }
- // Output image is ready.
- let outputImage = UIGraphicsGetImageFromCurrentImageContext()
- UIGraphicsEndImageContext()
- return outputImage
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement