Last active
November 7, 2019 20:07
-
-
Save devonc/a54ffb3541a7499ade3d to your computer and use it in GitHub Desktop.
Revisions
-
devonc revised this gist
Jul 18, 2015 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,4 @@ // Original from Apple https://developer.apple.com/library/ios/samplecode/UIImageEffects/Listings/UIImageEffects_UIImageEffects_m.html#//apple_ref/doc/uid/DTS40013396-UIImageEffects_UIImageEffects_m import Accelerate import UIKit @@ -76,7 +77,6 @@ extension UIImage { ] let divisor: CGFloat = 256 let saturationMatrix = floatingPointSaturationMatrix.map { return Int16(round($0 * divisor)) } -
devonc revised this gist
Jul 18, 2015 . 1 changed file with 136 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,136 @@ import Accelerate import UIKit extension UIImage { func applyLightEffect() -> UIImage? { return applyBlur(radius: 30, tintColor: UIColor(white: 1, alpha: 0.3)) } func applyExtraLightEffect() -> UIImage? { return applyBlur(radius: 20, tintColor: UIColor(white: 0.97, alpha: 0.82)) } func applyDarkEffect() -> UIImage? { return applyBlur(radius: 20, tintColor: UIColor(white: 0.11, alpha: 0.73)) } func applyTintEffect(color tintColor: UIColor) -> UIImage? { return applyBlur(radius: 10, tintColor: tintColor.colorWithAlphaComponent(0.6), saturationDeltaFactor: -1) } func applyBlur(radius blurRadius: CGFloat, tintColor: UIColor? = nil, saturationDeltaFactor: CGFloat = 1.8, maskImage: UIImage? = nil) -> UIImage? { if size.width < 1 || size.height < 1 { print(String(format: "*** error: invalid size: %.2f x %.2f. Both dimensions must be >= 1: \(self)", size.width, size.height)) return nil } if CGImage == nil { print("*** error: image must be backed by a CGImage: \(self)") return nil } if let maskImage = maskImage where maskImage.CGImage == nil { print("*** 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 = floatingPointSaturationMatrix.count let saturationMatrix = floatingPointSaturationMatrix.map { 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 } } -
devonc created this gist
Apr 16, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,136 @@ 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 } }