├── .gitignore ├── .swift-version ├── AFImageHelper.podspec ├── Demo iOS ├── AppDelegate.swift ├── Base.lproj │ └── Main.storyboard ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── LaunchImage.launchimage │ │ └── Contents.json │ └── beach.imageset │ │ ├── Contents.json │ │ └── beach.png ├── Info.plist ├── Launch Screen.xib └── ViewController.swift ├── Demo tvOS ├── AppDelegate.swift ├── Assets.xcassets │ ├── App Icon & Top Shelf Image.brandassets │ │ ├── App Icon - Large.imagestack │ │ │ ├── Back.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── Front.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ └── Middle.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ ├── App Icon - Small.imagestack │ │ │ ├── Back.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── Front.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ └── Middle.imagestacklayer │ │ │ │ ├── Content.imageset │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── Top Shelf Image Wide.imageset │ │ │ └── Contents.json │ │ └── Top Shelf Image.imageset │ │ │ └── Contents.json │ ├── Contents.json │ ├── LaunchImage.launchimage │ │ └── Contents.json │ └── beach.imageset │ │ ├── Contents.json │ │ └── beach.png ├── Base.lproj │ └── Main.storyboard └── Info.plist ├── ImageHelper.xcodeproj ├── project.pbxproj ├── project.xcworkspace.folder │ └── contents.xcworkspacedata ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── ImageHelper iOS.xcscheme │ └── ImageHelper tvOS.xcscheme ├── LICENSE ├── README.md ├── Screenshot.png └── Sources ├── ImageHelper.h ├── ImageHelper.swift ├── ImageVIewExtension.swift ├── Info-iOS.plist └── Info-tvOS.plist /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 3.0 2 | -------------------------------------------------------------------------------- /AFImageHelper.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint AFDateHelper.podspec' to ensure this is a 3 | # valid spec and remove all comments before submitting the spec. 4 | # 5 | # Any lines starting with a # are optional, but encouraged 6 | # 7 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 8 | # 9 | 10 | Pod::Spec.new do |s| 11 | s.name = "AFImageHelper" 12 | s.version = "3.2.2" 13 | s.summary = "Image Extensions for Swift 3.0" 14 | s.description = <<-DESC 15 | A collection of extensions for handling image creation from colors and gradients; Manipulating by cropping and scaling; Background fetching from the web with support for caching. 16 | DESC 17 | s.homepage = "https://github.com/melvitax/ImageHelper" 18 | s.screenshots = "https://raw.githubusercontent.com/melvitax/ImageHelper/master/Screenshot.png" 19 | s.license = 'MIT' 20 | s.author = { "Melvin Rivera" => "melvitax@gmail.com" } 21 | s.source = { :git => "https://github.com/melvitax/ImageHelper.git", :tag => s.version.to_s } 22 | s.social_media_url = 'https://twitter.com/melvitax' 23 | 24 | s.platforms = { :ios => '8.4', :tvos => '9.0' } 25 | s.ios.deployment_target = "8.4" 26 | s.tvos.deployment_target = "9.0" 27 | 28 | s.xcconfig = { 'SWIFT_VERSION' => '3.0' } 29 | 30 | s.source_files = "Sources/**/*.{h,swift}" 31 | 32 | end 33 | -------------------------------------------------------------------------------- /Demo iOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // AFImageHelper 4 | // 5 | // Created by Melvin Rivera on 7/5/14. 6 | // Copyright (c) 2014 All Forces. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | } 45 | 46 | -------------------------------------------------------------------------------- /Demo iOS/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /Demo iOS/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /Demo iOS/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /Demo iOS/Images.xcassets/beach.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "beach.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo iOS/Images.xcassets/beach.imageset/beach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/melvitax/ImageHelper/5dbb2547a33a1bbf4feff9a8f2bbd155ea26818d/Demo iOS/Images.xcassets/beach.imageset/beach.png -------------------------------------------------------------------------------- /Demo iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | Launch Screen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Demo iOS/Launch Screen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Demo iOS/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // AFImageHelper 4 | // 5 | // Created by Melvin Rivera on 7/5/14. 6 | // Copyright (c) 2014 All Forces. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import CoreImage 12 | 13 | struct CellItem { 14 | let text: String 15 | let image: UIImage 16 | } 17 | 18 | class Cell: UICollectionViewCell { 19 | @IBOutlet weak var imageView: UIImageView! 20 | @IBOutlet weak var textLabel: UILabel! 21 | } 22 | 23 | class ViewController: UICollectionViewController { 24 | 25 | let imageWidth = 140 * UIScreen.main.scale 26 | let imageHeight = 140 * UIScreen.main.scale 27 | 28 | var sections = [String]() 29 | var items = [[CellItem]]() 30 | 31 | override func viewDidLoad() { 32 | 33 | // Core Image 34 | 35 | // Colors & Gradients 36 | sections.append("Colors & Gradients") 37 | var colors = [CellItem]() 38 | if let image = UIImage(color: UIColor(red: 0.0, green: 0.502, blue: 1.0, alpha: 1.0), size: CGSize(width: imageWidth, height: imageHeight)) { 39 | colors.append(CellItem(text: "Solid Color", image: image)) 40 | } 41 | if let image = UIImage(gradientColors: [UIColor(red: 0.808, green: 0.863, blue: 0.902, alpha: 1.0), UIColor(red: 0.349, green: 0.412, blue: 0.443, alpha: 1.0)], size: CGSize(width: imageWidth, height: imageHeight)) { 42 | colors.append(CellItem(text: "Gradient Color", image: image)) 43 | } 44 | if let image = UIImage(named: "beach")?.apply(gradientColors: [UIColor(red: 0.996, green: 0.769, blue: 0.494, alpha: 1.0), UIColor(red: 0.969, green: 0.608, blue: 0.212, alpha: 0.2)]) { 45 | colors.append(CellItem(text: "Gradient Overlay", image: image)) 46 | } 47 | if let image = UIImage(named: "beach")?.apply(gradientColors: [UIColor.red, UIColor.green, UIColor.blue], locations: [0, 0.25, 0.99], blendMode: .normal) { 48 | colors.append(CellItem(text: "Gradient More", image: image)) 49 | } 50 | if let image = UIImage(startColor: UIColor(red: 0.996, green: 1.0, blue: 1.0, alpha: 1.0), endColor: UIColor(red: 0.627, green: 0.835, blue: 0.922, alpha: 1.0), radialGradientCenter: CGPoint(x: 0.5, y: 0.5), radius: 0.5, size: CGSize(width: imageWidth, height: imageHeight)) { 51 | colors.append(CellItem(text: "Radial Gradient", image: image)) 52 | } 53 | items.append(colors) 54 | 55 | 56 | // Text 57 | sections.append("Text") 58 | var text = [CellItem]() 59 | let textSize = 64 * UIScreen.main.scale 60 | if let image = UIImage(text: "M", font: UIFont.systemFont(ofSize: textSize), color: UIColor.white, backgroundColor: UIColor.red, size: CGSize(width: imageWidth, height: imageHeight))?.roundCornersToCircle() { 61 | text.append(CellItem(text: "Text Image", image: image)) 62 | } 63 | items.append(text) 64 | 65 | // Rounded Edges & Borders 66 | sections.append("Rounded Edges & Borders") 67 | var corners = [CellItem]() 68 | if let image = UIImage(named: "beach")?.roundCornersToCircle() { 69 | corners.append(CellItem(text: "Circle", image: image)) 70 | } 71 | let border = 12 * UIScreen.main.scale 72 | if let image = UIImage(named: "beach")?.roundCornersToCircle(withBorder: border, color: UIColor.lightGray) { 73 | corners.append(CellItem(text: "Circle + Border", image: image)) 74 | } 75 | if let image = UIImage(named: "beach")?.roundCorners(cornerRadius: 12) { 76 | corners.append(CellItem(text: "Round Corners", image: image)) 77 | } 78 | items.append(corners) 79 | 80 | 81 | // Cropping 82 | sections.append("Cropping") 83 | var cropping = [CellItem]() 84 | if let image = UIImage(named: "beach")?.crop(bounds: CGRect(x: 40.0, y: 40.0, width: imageWidth, height: imageHeight/2)) { 85 | cropping.append(CellItem(text: "Crop + Resize", image: image)) 86 | } 87 | items.append(cropping) 88 | 89 | // Effects 90 | sections.append("Image Effects") 91 | var effects = [CellItem]() 92 | if let image = UIImage(named: "beach")?.applyDarkEffect() { 93 | effects.append(CellItem(text: "Dark Effect", image: image)) 94 | } 95 | if let image = UIImage(named: "beach")?.applyLightEffect() { 96 | effects.append(CellItem(text: "Light Effect", image: image)) 97 | } 98 | if let image = UIImage(named: "beach")?.applyExtraLightEffect() { 99 | effects.append(CellItem(text: "Extra Light Effect", image: image)) 100 | } 101 | if let image = UIImage(named: "beach")?.applyTintEffect(tintColor: UIColor.red) { 102 | effects.append(CellItem(text: "Tint Effect", image: image)) 103 | } 104 | if let image = UIImage(named: "beach")?.applyBlur(withRadius: 10, tintColor: UIColor(white: 1.0, alpha: 0.3), saturationDeltaFactor: 1.8) { 105 | effects.append(CellItem(text: "Blur Effect", image: image)) 106 | } 107 | items.append(effects) 108 | 109 | // Web Image 110 | sections.append("Web Image") 111 | var web = [CellItem]() 112 | if let image = UIImage(color: UIColor.red) { 113 | web.append(CellItem(text: "From URL", image: image)) 114 | } 115 | items.append(web) 116 | 117 | super.viewDidLoad() 118 | } 119 | 120 | override func viewWillAppear(_ animated: Bool) { 121 | super.viewWillAppear(animated) 122 | 123 | } 124 | 125 | override func numberOfSections(in collectionView: UICollectionView) -> Int { 126 | return sections.count 127 | } 128 | 129 | override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { 130 | let headerView:UICollectionReusableView! = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "Header", for: indexPath) 131 | let textLabel = headerView.viewWithTag(1) as! UILabel 132 | textLabel.text = sections[(indexPath as NSIndexPath).section] 133 | return headerView 134 | } 135 | 136 | 137 | override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 138 | { 139 | return items[section].count 140 | } 141 | 142 | override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 143 | { 144 | let cellID = "Cell" 145 | let cell:Cell! = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! Cell 146 | 147 | let item: CellItem = items[(indexPath as NSIndexPath).section][(indexPath as NSIndexPath).item] 148 | cell.textLabel.text = item.text 149 | 150 | 151 | // Last image is a web request 152 | if ((indexPath as NSIndexPath).section == items.count-1) { 153 | cell.imageView.imageFromURL("https://c2.staticflickr.com/4/3212/3130969018_ed7516c288_n.jpg", placeholder: item.image, fadeIn: true) { 154 | (image: UIImage?) in 155 | if image != nil { 156 | cell.imageView.image = image! 157 | } 158 | } 159 | } else { 160 | cell.imageView.image = item.image 161 | } 162 | 163 | return cell 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /Demo tvOS/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Demo tvOS 4 | // 5 | // Created by Melvin Rivera on 9/16/16. 6 | // Copyright © 2016 All Forces. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers" : [ 3 | { 4 | "filename" : "Front.imagestacklayer" 5 | }, 6 | { 7 | "filename" : "Middle.imagestacklayer" 8 | }, 9 | { 10 | "filename" : "Back.imagestacklayer" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "layers" : [ 3 | { 4 | "filename" : "Front.imagestacklayer" 5 | }, 6 | { 7 | "filename" : "Middle.imagestacklayer" 8 | }, 9 | { 10 | "filename" : "Back.imagestacklayer" 11 | } 12 | ], 13 | "info" : { 14 | "version" : 1, 15 | "author" : "xcode" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "assets" : [ 3 | { 4 | "size" : "1280x768", 5 | "idiom" : "tv", 6 | "filename" : "App Icon - Large.imagestack", 7 | "role" : "primary-app-icon" 8 | }, 9 | { 10 | "size" : "400x240", 11 | "idiom" : "tv", 12 | "filename" : "App Icon - Small.imagestack", 13 | "role" : "primary-app-icon" 14 | }, 15 | { 16 | "size" : "2320x720", 17 | "idiom" : "tv", 18 | "filename" : "Top Shelf Image Wide.imageset", 19 | "role" : "top-shelf-image-wide" 20 | }, 21 | { 22 | "size" : "1920x720", 23 | "idiom" : "tv", 24 | "filename" : "Top Shelf Image.imageset", 25 | "role" : "top-shelf-image" 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "tv", 5 | "scale" : "1x" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "landscape", 5 | "idiom" : "tv", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "9.0", 8 | "scale" : "1x" 9 | } 10 | ], 11 | "info" : { 12 | "version" : 1, 13 | "author" : "xcode" 14 | } 15 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/beach.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "beach.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo tvOS/Assets.xcassets/beach.imageset/beach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/melvitax/ImageHelper/5dbb2547a33a1bbf4feff9a8f2bbd155ea26818d/Demo tvOS/Assets.xcassets/beach.imageset/beach.png -------------------------------------------------------------------------------- /Demo tvOS/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /Demo tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIMainStoryboardFile 24 | Main 25 | UIRequiredDeviceCapabilities 26 | 27 | arm64 28 | 29 | UIUserInterfaceStyle 30 | Automatic 31 | 32 | 33 | -------------------------------------------------------------------------------- /ImageHelper.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 65D016A819772100005220FB /* AFImageHelper.podspec in Resources */ = {isa = PBXBuildFile; fileRef = 65D016A719772100005220FB /* AFImageHelper.podspec */; }; 11 | 65EAC4A01D8C410D0001F670 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EAC4991D8C410D0001F670 /* AppDelegate.swift */; }; 12 | 65EAC4A11D8C410D0001F670 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 65EAC49A1D8C410D0001F670 /* Main.storyboard */; }; 13 | 65EAC4A21D8C410D0001F670 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 65EAC49C1D8C410D0001F670 /* Images.xcassets */; }; 14 | 65EAC4A31D8C410D0001F670 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 65EAC49D1D8C410D0001F670 /* Info.plist */; }; 15 | 65EAC4A41D8C410D0001F670 /* Launch Screen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65EAC49E1D8C410D0001F670 /* Launch Screen.xib */; }; 16 | 65EAC4A51D8C410D0001F670 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EAC49F1D8C410D0001F670 /* ViewController.swift */; }; 17 | 65EAC4B71D8C42170001F670 /* ImageHelper.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65EAC4B01D8C42170001F670 /* ImageHelper.framework */; }; 18 | 65EAC4B81D8C42170001F670 /* ImageHelper.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 65EAC4B01D8C42170001F670 /* ImageHelper.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 19 | 65EAC4DD1D8C42E40001F670 /* ImageHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EAC4D71D8C42E40001F670 /* ImageHelper.swift */; }; 20 | 65EAC4DE1D8C42E40001F670 /* ImageVIewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EAC4D91D8C42E40001F670 /* ImageVIewExtension.swift */; }; 21 | 65F5EC2F1D8C441C004A35E8 /* ImageHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 65EAC4D81D8C42E40001F670 /* ImageHelper.h */; settings = {ATTRIBUTES = (Public, ); }; }; 22 | 65F5EC301D8C441D004A35E8 /* ImageHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 65EAC4D81D8C42E40001F670 /* ImageHelper.h */; settings = {ATTRIBUTES = (Public, ); }; }; 23 | 65F5EC311D8C441E004A35E8 /* ImageHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 65EAC4D81D8C42E40001F670 /* ImageHelper.h */; settings = {ATTRIBUTES = (Public, ); }; }; 24 | 65F5EC321D8C4472004A35E8 /* ImageHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EAC4D71D8C42E40001F670 /* ImageHelper.swift */; }; 25 | 65F5EC331D8C4473004A35E8 /* ImageHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EAC4D71D8C42E40001F670 /* ImageHelper.swift */; }; 26 | 65F5EC341D8C4473004A35E8 /* ImageHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EAC4D71D8C42E40001F670 /* ImageHelper.swift */; }; 27 | 65F5EC351D8C4476004A35E8 /* ImageVIewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EAC4D91D8C42E40001F670 /* ImageVIewExtension.swift */; }; 28 | 65F5EC361D8C4477004A35E8 /* ImageVIewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EAC4D91D8C42E40001F670 /* ImageVIewExtension.swift */; }; 29 | 65F5EC371D8C4478004A35E8 /* ImageVIewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EAC4D91D8C42E40001F670 /* ImageVIewExtension.swift */; }; 30 | 65F5EC401D8C493C004A35E8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F5EC3F1D8C493C004A35E8 /* AppDelegate.swift */; }; 31 | 65F5EC451D8C493C004A35E8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 65F5EC431D8C493C004A35E8 /* Main.storyboard */; }; 32 | 65F5EC471D8C493C004A35E8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 65F5EC461D8C493C004A35E8 /* Assets.xcassets */; }; 33 | 65F5EC4C1D8C49ED004A35E8 /* ImageVIewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EAC4D91D8C42E40001F670 /* ImageVIewExtension.swift */; }; 34 | 65F5EC4D1D8C49F0004A35E8 /* ImageHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EAC4D71D8C42E40001F670 /* ImageHelper.swift */; }; 35 | 65F5EC4E1D8C4D28004A35E8 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EAC49F1D8C410D0001F670 /* ViewController.swift */; }; 36 | 65F5EC4F1D8C52BA004A35E8 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 65F5EC481D8C493C004A35E8 /* Info.plist */; }; 37 | /* End PBXBuildFile section */ 38 | 39 | /* Begin PBXContainerItemProxy section */ 40 | 65EAC4B51D8C42170001F670 /* PBXContainerItemProxy */ = { 41 | isa = PBXContainerItemProxy; 42 | containerPortal = 65613677192E526900E30E76 /* Project object */; 43 | proxyType = 1; 44 | remoteGlobalIDString = 65EAC4AF1D8C42170001F670; 45 | remoteInfo = "ImageHelper iOS"; 46 | }; 47 | /* End PBXContainerItemProxy section */ 48 | 49 | /* Begin PBXCopyFilesBuildPhase section */ 50 | 65EAC4BC1D8C42170001F670 /* Embed Frameworks */ = { 51 | isa = PBXCopyFilesBuildPhase; 52 | buildActionMask = 2147483647; 53 | dstPath = ""; 54 | dstSubfolderSpec = 10; 55 | files = ( 56 | 65EAC4B81D8C42170001F670 /* ImageHelper.framework in Embed Frameworks */, 57 | ); 58 | name = "Embed Frameworks"; 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXCopyFilesBuildPhase section */ 62 | 63 | /* Begin PBXFileReference section */ 64 | 65613682192E526900E30E76 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 65 | 65613684192E526900E30E76 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 66 | 65613686192E526900E30E76 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 67 | 656136A4192E526900E30E76 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 68 | 6581F3D61968328100C5CA28 /* AFImageHelper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AFImageHelper.app; sourceTree = BUILT_PRODUCTS_DIR; }; 69 | 65B7EA71197067D70097E598 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 70 | 65D016A719772100005220FB /* AFImageHelper.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AFImageHelper.podspec; sourceTree = ""; }; 71 | 65EAC4991D8C410D0001F670 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 72 | 65EAC49B1D8C410D0001F670 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 73 | 65EAC49C1D8C410D0001F670 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 74 | 65EAC49D1D8C410D0001F670 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 75 | 65EAC49E1D8C410D0001F670 /* Launch Screen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "Launch Screen.xib"; sourceTree = ""; }; 76 | 65EAC49F1D8C410D0001F670 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 77 | 65EAC4B01D8C42170001F670 /* ImageHelper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ImageHelper.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 78 | 65EAC4C21D8C42270001F670 /* ImageHelper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ImageHelper.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 79 | 65EAC4CF1D8C423D0001F670 /* ImageHelper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ImageHelper.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 80 | 65EAC4D71D8C42E40001F670 /* ImageHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageHelper.swift; sourceTree = ""; }; 81 | 65EAC4D81D8C42E40001F670 /* ImageHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageHelper.h; sourceTree = ""; }; 82 | 65EAC4D91D8C42E40001F670 /* ImageVIewExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageVIewExtension.swift; sourceTree = ""; }; 83 | 65EAC4DA1D8C42E40001F670 /* Info-iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; }; 84 | 65EAC4DB1D8C42E40001F670 /* Info-tvOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = ""; }; 85 | 65F5EC3D1D8C493C004A35E8 /* Demo tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Demo tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 86 | 65F5EC3F1D8C493C004A35E8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 87 | 65F5EC441D8C493C004A35E8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 88 | 65F5EC461D8C493C004A35E8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 89 | 65F5EC481D8C493C004A35E8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 90 | /* End PBXFileReference section */ 91 | 92 | /* Begin PBXFrameworksBuildPhase section */ 93 | 6581F3D31968328100C5CA28 /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | 65EAC4B71D8C42170001F670 /* ImageHelper.framework in Frameworks */, 98 | ); 99 | runOnlyForDeploymentPostprocessing = 0; 100 | }; 101 | 65EAC4AC1D8C42170001F670 /* Frameworks */ = { 102 | isa = PBXFrameworksBuildPhase; 103 | buildActionMask = 2147483647; 104 | files = ( 105 | ); 106 | runOnlyForDeploymentPostprocessing = 0; 107 | }; 108 | 65EAC4BE1D8C42270001F670 /* Frameworks */ = { 109 | isa = PBXFrameworksBuildPhase; 110 | buildActionMask = 2147483647; 111 | files = ( 112 | ); 113 | runOnlyForDeploymentPostprocessing = 0; 114 | }; 115 | 65EAC4CB1D8C423D0001F670 /* Frameworks */ = { 116 | isa = PBXFrameworksBuildPhase; 117 | buildActionMask = 2147483647; 118 | files = ( 119 | ); 120 | runOnlyForDeploymentPostprocessing = 0; 121 | }; 122 | 65F5EC3A1D8C493C004A35E8 /* Frameworks */ = { 123 | isa = PBXFrameworksBuildPhase; 124 | buildActionMask = 2147483647; 125 | files = ( 126 | ); 127 | runOnlyForDeploymentPostprocessing = 0; 128 | }; 129 | /* End PBXFrameworksBuildPhase section */ 130 | 131 | /* Begin PBXGroup section */ 132 | 65613676192E526900E30E76 = { 133 | isa = PBXGroup; 134 | children = ( 135 | 65EAC4A61D8C411C0001F670 /* Sources */, 136 | 65EAC4981D8C410D0001F670 /* Demo iOS */, 137 | 65B7EA71197067D70097E598 /* README.md */, 138 | 65D016A719772100005220FB /* AFImageHelper.podspec */, 139 | 65F5EC3E1D8C493C004A35E8 /* Demo tvOS */, 140 | 65613681192E526900E30E76 /* Frameworks */, 141 | 65613680192E526900E30E76 /* Products */, 142 | ); 143 | sourceTree = ""; 144 | }; 145 | 65613680192E526900E30E76 /* Products */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | 6581F3D61968328100C5CA28 /* AFImageHelper.app */, 149 | 65EAC4B01D8C42170001F670 /* ImageHelper.framework */, 150 | 65EAC4C21D8C42270001F670 /* ImageHelper.framework */, 151 | 65EAC4CF1D8C423D0001F670 /* ImageHelper.framework */, 152 | 65F5EC3D1D8C493C004A35E8 /* Demo tvOS.app */, 153 | ); 154 | name = Products; 155 | sourceTree = ""; 156 | }; 157 | 65613681192E526900E30E76 /* Frameworks */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | 65613682192E526900E30E76 /* Foundation.framework */, 161 | 65613684192E526900E30E76 /* CoreGraphics.framework */, 162 | 65613686192E526900E30E76 /* UIKit.framework */, 163 | 656136A4192E526900E30E76 /* XCTest.framework */, 164 | ); 165 | name = Frameworks; 166 | sourceTree = ""; 167 | }; 168 | 65EAC4981D8C410D0001F670 /* Demo iOS */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | 65EAC4991D8C410D0001F670 /* AppDelegate.swift */, 172 | 65EAC49A1D8C410D0001F670 /* Main.storyboard */, 173 | 65EAC49C1D8C410D0001F670 /* Images.xcassets */, 174 | 65EAC49D1D8C410D0001F670 /* Info.plist */, 175 | 65EAC49E1D8C410D0001F670 /* Launch Screen.xib */, 176 | 65EAC49F1D8C410D0001F670 /* ViewController.swift */, 177 | ); 178 | path = "Demo iOS"; 179 | sourceTree = ""; 180 | }; 181 | 65EAC4A61D8C411C0001F670 /* Sources */ = { 182 | isa = PBXGroup; 183 | children = ( 184 | 65EAC4D71D8C42E40001F670 /* ImageHelper.swift */, 185 | 65EAC4D91D8C42E40001F670 /* ImageVIewExtension.swift */, 186 | 65EAC4D81D8C42E40001F670 /* ImageHelper.h */, 187 | 65EAC4DA1D8C42E40001F670 /* Info-iOS.plist */, 188 | 65EAC4DB1D8C42E40001F670 /* Info-tvOS.plist */, 189 | ); 190 | path = Sources; 191 | sourceTree = SOURCE_ROOT; 192 | }; 193 | 65F5EC3E1D8C493C004A35E8 /* Demo tvOS */ = { 194 | isa = PBXGroup; 195 | children = ( 196 | 65F5EC3F1D8C493C004A35E8 /* AppDelegate.swift */, 197 | 65F5EC431D8C493C004A35E8 /* Main.storyboard */, 198 | 65F5EC461D8C493C004A35E8 /* Assets.xcassets */, 199 | 65F5EC481D8C493C004A35E8 /* Info.plist */, 200 | ); 201 | path = "Demo tvOS"; 202 | sourceTree = ""; 203 | }; 204 | /* End PBXGroup section */ 205 | 206 | /* Begin PBXHeadersBuildPhase section */ 207 | 65EAC4AD1D8C42170001F670 /* Headers */ = { 208 | isa = PBXHeadersBuildPhase; 209 | buildActionMask = 2147483647; 210 | files = ( 211 | 65F5EC311D8C441E004A35E8 /* ImageHelper.h in Headers */, 212 | ); 213 | runOnlyForDeploymentPostprocessing = 0; 214 | }; 215 | 65EAC4BF1D8C42270001F670 /* Headers */ = { 216 | isa = PBXHeadersBuildPhase; 217 | buildActionMask = 2147483647; 218 | files = ( 219 | 65F5EC301D8C441D004A35E8 /* ImageHelper.h in Headers */, 220 | ); 221 | runOnlyForDeploymentPostprocessing = 0; 222 | }; 223 | 65EAC4CC1D8C423D0001F670 /* Headers */ = { 224 | isa = PBXHeadersBuildPhase; 225 | buildActionMask = 2147483647; 226 | files = ( 227 | 65F5EC2F1D8C441C004A35E8 /* ImageHelper.h in Headers */, 228 | ); 229 | runOnlyForDeploymentPostprocessing = 0; 230 | }; 231 | /* End PBXHeadersBuildPhase section */ 232 | 233 | /* Begin PBXNativeTarget section */ 234 | 6581F3D51968328100C5CA28 /* Demo iOS */ = { 235 | isa = PBXNativeTarget; 236 | buildConfigurationList = 6581F3EF1968328200C5CA28 /* Build configuration list for PBXNativeTarget "Demo iOS" */; 237 | buildPhases = ( 238 | 6581F3D21968328100C5CA28 /* Sources */, 239 | 6581F3D31968328100C5CA28 /* Frameworks */, 240 | 6581F3D41968328100C5CA28 /* Resources */, 241 | 65EAC4BC1D8C42170001F670 /* Embed Frameworks */, 242 | ); 243 | buildRules = ( 244 | ); 245 | dependencies = ( 246 | 65EAC4B61D8C42170001F670 /* PBXTargetDependency */, 247 | ); 248 | name = "Demo iOS"; 249 | productName = "Swift Demo UIImage+AF+Additions"; 250 | productReference = 6581F3D61968328100C5CA28 /* AFImageHelper.app */; 251 | productType = "com.apple.product-type.application"; 252 | }; 253 | 65EAC4AF1D8C42170001F670 /* ImageHelper iOS */ = { 254 | isa = PBXNativeTarget; 255 | buildConfigurationList = 65EAC4B91D8C42170001F670 /* Build configuration list for PBXNativeTarget "ImageHelper iOS" */; 256 | buildPhases = ( 257 | 65EAC4AB1D8C42170001F670 /* Sources */, 258 | 65EAC4AC1D8C42170001F670 /* Frameworks */, 259 | 65EAC4AD1D8C42170001F670 /* Headers */, 260 | 65EAC4AE1D8C42170001F670 /* Resources */, 261 | ); 262 | buildRules = ( 263 | ); 264 | dependencies = ( 265 | ); 266 | name = "ImageHelper iOS"; 267 | productName = "ImageHelper iOS"; 268 | productReference = 65EAC4B01D8C42170001F670 /* ImageHelper.framework */; 269 | productType = "com.apple.product-type.framework"; 270 | }; 271 | 65EAC4C11D8C42270001F670 /* ImageHelper watchOS */ = { 272 | isa = PBXNativeTarget; 273 | buildConfigurationList = 65EAC4C71D8C42270001F670 /* Build configuration list for PBXNativeTarget "ImageHelper watchOS" */; 274 | buildPhases = ( 275 | 65EAC4BD1D8C42270001F670 /* Sources */, 276 | 65EAC4BE1D8C42270001F670 /* Frameworks */, 277 | 65EAC4BF1D8C42270001F670 /* Headers */, 278 | 65EAC4C01D8C42270001F670 /* Resources */, 279 | ); 280 | buildRules = ( 281 | ); 282 | dependencies = ( 283 | ); 284 | name = "ImageHelper watchOS"; 285 | productName = "ImageHelper watchOS"; 286 | productReference = 65EAC4C21D8C42270001F670 /* ImageHelper.framework */; 287 | productType = "com.apple.product-type.framework"; 288 | }; 289 | 65EAC4CE1D8C423D0001F670 /* ImageHelper tvOS */ = { 290 | isa = PBXNativeTarget; 291 | buildConfigurationList = 65EAC4D41D8C423D0001F670 /* Build configuration list for PBXNativeTarget "ImageHelper tvOS" */; 292 | buildPhases = ( 293 | 65EAC4CA1D8C423D0001F670 /* Sources */, 294 | 65EAC4CB1D8C423D0001F670 /* Frameworks */, 295 | 65EAC4CC1D8C423D0001F670 /* Headers */, 296 | 65EAC4CD1D8C423D0001F670 /* Resources */, 297 | ); 298 | buildRules = ( 299 | ); 300 | dependencies = ( 301 | ); 302 | name = "ImageHelper tvOS"; 303 | productName = "ImageHelper tvOS"; 304 | productReference = 65EAC4CF1D8C423D0001F670 /* ImageHelper.framework */; 305 | productType = "com.apple.product-type.framework"; 306 | }; 307 | 65F5EC3C1D8C493C004A35E8 /* Demo tvOS */ = { 308 | isa = PBXNativeTarget; 309 | buildConfigurationList = 65F5EC491D8C493C004A35E8 /* Build configuration list for PBXNativeTarget "Demo tvOS" */; 310 | buildPhases = ( 311 | 65F5EC391D8C493C004A35E8 /* Sources */, 312 | 65F5EC3A1D8C493C004A35E8 /* Frameworks */, 313 | 65F5EC3B1D8C493C004A35E8 /* Resources */, 314 | ); 315 | buildRules = ( 316 | ); 317 | dependencies = ( 318 | ); 319 | name = "Demo tvOS"; 320 | productName = "Demo tvOS"; 321 | productReference = 65F5EC3D1D8C493C004A35E8 /* Demo tvOS.app */; 322 | productType = "com.apple.product-type.application"; 323 | }; 324 | /* End PBXNativeTarget section */ 325 | 326 | /* Begin PBXProject section */ 327 | 65613677192E526900E30E76 /* Project object */ = { 328 | isa = PBXProject; 329 | attributes = { 330 | LastSwiftUpdateCheck = 0800; 331 | LastUpgradeCheck = 0800; 332 | ORGANIZATIONNAME = "All Forces"; 333 | TargetAttributes = { 334 | 6581F3D51968328100C5CA28 = { 335 | CreatedOnToolsVersion = 6.0; 336 | DevelopmentTeam = ERA9S8SPNY; 337 | LastSwiftMigration = 0800; 338 | }; 339 | 65EAC4AF1D8C42170001F670 = { 340 | CreatedOnToolsVersion = 8.0; 341 | DevelopmentTeam = ERA9S8SPNY; 342 | ProvisioningStyle = Automatic; 343 | }; 344 | 65EAC4C11D8C42270001F670 = { 345 | CreatedOnToolsVersion = 8.0; 346 | ProvisioningStyle = Automatic; 347 | }; 348 | 65EAC4CE1D8C423D0001F670 = { 349 | CreatedOnToolsVersion = 8.0; 350 | ProvisioningStyle = Automatic; 351 | }; 352 | 65F5EC3C1D8C493C004A35E8 = { 353 | CreatedOnToolsVersion = 8.0; 354 | ProvisioningStyle = Automatic; 355 | }; 356 | }; 357 | }; 358 | buildConfigurationList = 6561367A192E526900E30E76 /* Build configuration list for PBXProject "ImageHelper" */; 359 | compatibilityVersion = "Xcode 3.2"; 360 | developmentRegion = English; 361 | hasScannedForEncodings = 0; 362 | knownRegions = ( 363 | en, 364 | Base, 365 | ); 366 | mainGroup = 65613676192E526900E30E76; 367 | productRefGroup = 65613680192E526900E30E76 /* Products */; 368 | projectDirPath = ""; 369 | projectRoot = ""; 370 | targets = ( 371 | 6581F3D51968328100C5CA28 /* Demo iOS */, 372 | 65F5EC3C1D8C493C004A35E8 /* Demo tvOS */, 373 | 65EAC4AF1D8C42170001F670 /* ImageHelper iOS */, 374 | 65EAC4C11D8C42270001F670 /* ImageHelper watchOS */, 375 | 65EAC4CE1D8C423D0001F670 /* ImageHelper tvOS */, 376 | ); 377 | }; 378 | /* End PBXProject section */ 379 | 380 | /* Begin PBXResourcesBuildPhase section */ 381 | 6581F3D41968328100C5CA28 /* Resources */ = { 382 | isa = PBXResourcesBuildPhase; 383 | buildActionMask = 2147483647; 384 | files = ( 385 | 65D016A819772100005220FB /* AFImageHelper.podspec in Resources */, 386 | 65EAC4A11D8C410D0001F670 /* Main.storyboard in Resources */, 387 | 65EAC4A21D8C410D0001F670 /* Images.xcassets in Resources */, 388 | 65EAC4A41D8C410D0001F670 /* Launch Screen.xib in Resources */, 389 | 65EAC4A31D8C410D0001F670 /* Info.plist in Resources */, 390 | ); 391 | runOnlyForDeploymentPostprocessing = 0; 392 | }; 393 | 65EAC4AE1D8C42170001F670 /* Resources */ = { 394 | isa = PBXResourcesBuildPhase; 395 | buildActionMask = 2147483647; 396 | files = ( 397 | ); 398 | runOnlyForDeploymentPostprocessing = 0; 399 | }; 400 | 65EAC4C01D8C42270001F670 /* Resources */ = { 401 | isa = PBXResourcesBuildPhase; 402 | buildActionMask = 2147483647; 403 | files = ( 404 | ); 405 | runOnlyForDeploymentPostprocessing = 0; 406 | }; 407 | 65EAC4CD1D8C423D0001F670 /* Resources */ = { 408 | isa = PBXResourcesBuildPhase; 409 | buildActionMask = 2147483647; 410 | files = ( 411 | ); 412 | runOnlyForDeploymentPostprocessing = 0; 413 | }; 414 | 65F5EC3B1D8C493C004A35E8 /* Resources */ = { 415 | isa = PBXResourcesBuildPhase; 416 | buildActionMask = 2147483647; 417 | files = ( 418 | 65F5EC471D8C493C004A35E8 /* Assets.xcassets in Resources */, 419 | 65F5EC451D8C493C004A35E8 /* Main.storyboard in Resources */, 420 | 65F5EC4F1D8C52BA004A35E8 /* Info.plist in Resources */, 421 | ); 422 | runOnlyForDeploymentPostprocessing = 0; 423 | }; 424 | /* End PBXResourcesBuildPhase section */ 425 | 426 | /* Begin PBXSourcesBuildPhase section */ 427 | 6581F3D21968328100C5CA28 /* Sources */ = { 428 | isa = PBXSourcesBuildPhase; 429 | buildActionMask = 2147483647; 430 | files = ( 431 | 65EAC4A51D8C410D0001F670 /* ViewController.swift in Sources */, 432 | 65EAC4DD1D8C42E40001F670 /* ImageHelper.swift in Sources */, 433 | 65EAC4DE1D8C42E40001F670 /* ImageVIewExtension.swift in Sources */, 434 | 65EAC4A01D8C410D0001F670 /* AppDelegate.swift in Sources */, 435 | ); 436 | runOnlyForDeploymentPostprocessing = 0; 437 | }; 438 | 65EAC4AB1D8C42170001F670 /* Sources */ = { 439 | isa = PBXSourcesBuildPhase; 440 | buildActionMask = 2147483647; 441 | files = ( 442 | 65F5EC371D8C4478004A35E8 /* ImageVIewExtension.swift in Sources */, 443 | 65F5EC341D8C4473004A35E8 /* ImageHelper.swift in Sources */, 444 | ); 445 | runOnlyForDeploymentPostprocessing = 0; 446 | }; 447 | 65EAC4BD1D8C42270001F670 /* Sources */ = { 448 | isa = PBXSourcesBuildPhase; 449 | buildActionMask = 2147483647; 450 | files = ( 451 | 65F5EC361D8C4477004A35E8 /* ImageVIewExtension.swift in Sources */, 452 | 65F5EC331D8C4473004A35E8 /* ImageHelper.swift in Sources */, 453 | ); 454 | runOnlyForDeploymentPostprocessing = 0; 455 | }; 456 | 65EAC4CA1D8C423D0001F670 /* Sources */ = { 457 | isa = PBXSourcesBuildPhase; 458 | buildActionMask = 2147483647; 459 | files = ( 460 | 65F5EC351D8C4476004A35E8 /* ImageVIewExtension.swift in Sources */, 461 | 65F5EC321D8C4472004A35E8 /* ImageHelper.swift in Sources */, 462 | ); 463 | runOnlyForDeploymentPostprocessing = 0; 464 | }; 465 | 65F5EC391D8C493C004A35E8 /* Sources */ = { 466 | isa = PBXSourcesBuildPhase; 467 | buildActionMask = 2147483647; 468 | files = ( 469 | 65F5EC4C1D8C49ED004A35E8 /* ImageVIewExtension.swift in Sources */, 470 | 65F5EC401D8C493C004A35E8 /* AppDelegate.swift in Sources */, 471 | 65F5EC4E1D8C4D28004A35E8 /* ViewController.swift in Sources */, 472 | 65F5EC4D1D8C49F0004A35E8 /* ImageHelper.swift in Sources */, 473 | ); 474 | runOnlyForDeploymentPostprocessing = 0; 475 | }; 476 | /* End PBXSourcesBuildPhase section */ 477 | 478 | /* Begin PBXTargetDependency section */ 479 | 65EAC4B61D8C42170001F670 /* PBXTargetDependency */ = { 480 | isa = PBXTargetDependency; 481 | target = 65EAC4AF1D8C42170001F670 /* ImageHelper iOS */; 482 | targetProxy = 65EAC4B51D8C42170001F670 /* PBXContainerItemProxy */; 483 | }; 484 | /* End PBXTargetDependency section */ 485 | 486 | /* Begin PBXVariantGroup section */ 487 | 65EAC49A1D8C410D0001F670 /* Main.storyboard */ = { 488 | isa = PBXVariantGroup; 489 | children = ( 490 | 65EAC49B1D8C410D0001F670 /* Base */, 491 | ); 492 | name = Main.storyboard; 493 | sourceTree = ""; 494 | }; 495 | 65F5EC431D8C493C004A35E8 /* Main.storyboard */ = { 496 | isa = PBXVariantGroup; 497 | children = ( 498 | 65F5EC441D8C493C004A35E8 /* Base */, 499 | ); 500 | name = Main.storyboard; 501 | sourceTree = ""; 502 | }; 503 | /* End PBXVariantGroup section */ 504 | 505 | /* Begin XCBuildConfiguration section */ 506 | 656136B2192E526900E30E76 /* Debug */ = { 507 | isa = XCBuildConfiguration; 508 | buildSettings = { 509 | ALWAYS_SEARCH_USER_PATHS = NO; 510 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 511 | CLANG_CXX_LIBRARY = "libc++"; 512 | CLANG_ENABLE_MODULES = YES; 513 | CLANG_ENABLE_OBJC_ARC = YES; 514 | CLANG_WARN_BOOL_CONVERSION = YES; 515 | CLANG_WARN_CONSTANT_CONVERSION = YES; 516 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 517 | CLANG_WARN_EMPTY_BODY = YES; 518 | CLANG_WARN_ENUM_CONVERSION = YES; 519 | CLANG_WARN_INFINITE_RECURSION = YES; 520 | CLANG_WARN_INT_CONVERSION = YES; 521 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 522 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 523 | CLANG_WARN_UNREACHABLE_CODE = YES; 524 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 525 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 526 | COPY_PHASE_STRIP = NO; 527 | ENABLE_STRICT_OBJC_MSGSEND = YES; 528 | ENABLE_TESTABILITY = YES; 529 | GCC_C_LANGUAGE_STANDARD = gnu99; 530 | GCC_DYNAMIC_NO_PIC = NO; 531 | GCC_NO_COMMON_BLOCKS = YES; 532 | GCC_OPTIMIZATION_LEVEL = 0; 533 | GCC_PREPROCESSOR_DEFINITIONS = ( 534 | "DEBUG=1", 535 | "$(inherited)", 536 | ); 537 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 538 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 539 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 540 | GCC_WARN_UNDECLARED_SELECTOR = YES; 541 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 542 | GCC_WARN_UNUSED_FUNCTION = YES; 543 | GCC_WARN_UNUSED_VARIABLE = YES; 544 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 545 | ONLY_ACTIVE_ARCH = YES; 546 | SDKROOT = iphoneos; 547 | TARGETED_DEVICE_FAMILY = "1,2"; 548 | }; 549 | name = Debug; 550 | }; 551 | 656136B3192E526900E30E76 /* Release */ = { 552 | isa = XCBuildConfiguration; 553 | buildSettings = { 554 | ALWAYS_SEARCH_USER_PATHS = NO; 555 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 556 | CLANG_CXX_LIBRARY = "libc++"; 557 | CLANG_ENABLE_MODULES = YES; 558 | CLANG_ENABLE_OBJC_ARC = YES; 559 | CLANG_WARN_BOOL_CONVERSION = YES; 560 | CLANG_WARN_CONSTANT_CONVERSION = YES; 561 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 562 | CLANG_WARN_EMPTY_BODY = YES; 563 | CLANG_WARN_ENUM_CONVERSION = YES; 564 | CLANG_WARN_INFINITE_RECURSION = YES; 565 | CLANG_WARN_INT_CONVERSION = YES; 566 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 567 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 568 | CLANG_WARN_UNREACHABLE_CODE = YES; 569 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 570 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 571 | COPY_PHASE_STRIP = YES; 572 | ENABLE_NS_ASSERTIONS = NO; 573 | ENABLE_STRICT_OBJC_MSGSEND = YES; 574 | GCC_C_LANGUAGE_STANDARD = gnu99; 575 | GCC_NO_COMMON_BLOCKS = YES; 576 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 577 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 578 | GCC_WARN_UNDECLARED_SELECTOR = YES; 579 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 580 | GCC_WARN_UNUSED_FUNCTION = YES; 581 | GCC_WARN_UNUSED_VARIABLE = YES; 582 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 583 | SDKROOT = iphoneos; 584 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 585 | TARGETED_DEVICE_FAMILY = "1,2"; 586 | VALIDATE_PRODUCT = YES; 587 | }; 588 | name = Release; 589 | }; 590 | 6581F3F01968328200C5CA28 /* Debug */ = { 591 | isa = XCBuildConfiguration; 592 | buildSettings = { 593 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 594 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 595 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 596 | CLANG_WARN_UNREACHABLE_CODE = YES; 597 | DEVELOPMENT_TEAM = ERA9S8SPNY; 598 | ENABLE_STRICT_OBJC_MSGSEND = YES; 599 | GCC_PREPROCESSOR_DEFINITIONS = ( 600 | "DEBUG=1", 601 | "$(inherited)", 602 | ); 603 | INFOPLIST_FILE = "$(SRCROOT)/Demo iOS/Info.plist"; 604 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 605 | METAL_ENABLE_DEBUG_INFO = YES; 606 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ImageHelperDemo-iOS"; 607 | PRODUCT_NAME = AFImageHelper; 608 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 609 | SWIFT_VERSION = 3.0; 610 | }; 611 | name = Debug; 612 | }; 613 | 6581F3F11968328200C5CA28 /* Release */ = { 614 | isa = XCBuildConfiguration; 615 | buildSettings = { 616 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 617 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 618 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 619 | CLANG_WARN_UNREACHABLE_CODE = YES; 620 | DEVELOPMENT_TEAM = ERA9S8SPNY; 621 | ENABLE_STRICT_OBJC_MSGSEND = YES; 622 | INFOPLIST_FILE = "$(SRCROOT)/Demo iOS/Info.plist"; 623 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 624 | METAL_ENABLE_DEBUG_INFO = NO; 625 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ImageHelperDemo-iOS"; 626 | PRODUCT_NAME = AFImageHelper; 627 | SWIFT_VERSION = 3.0; 628 | }; 629 | name = Release; 630 | }; 631 | 65EAC4BA1D8C42170001F670 /* Debug */ = { 632 | isa = XCBuildConfiguration; 633 | buildSettings = { 634 | APPLICATION_EXTENSION_API_ONLY = YES; 635 | CLANG_ANALYZER_NONNULL = YES; 636 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 637 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 638 | CODE_SIGN_IDENTITY = ""; 639 | CURRENT_PROJECT_VERSION = 1; 640 | DEBUG_INFORMATION_FORMAT = dwarf; 641 | DEFINES_MODULE = YES; 642 | DEVELOPMENT_TEAM = ERA9S8SPNY; 643 | DYLIB_COMPATIBILITY_VERSION = 1; 644 | DYLIB_CURRENT_VERSION = 1; 645 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 646 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-iOS.plist"; 647 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 648 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 649 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 650 | MTL_ENABLE_DEBUG_INFO = YES; 651 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ImageHelper-iOS"; 652 | PRODUCT_NAME = ImageHelper; 653 | SKIP_INSTALL = YES; 654 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 655 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 656 | SWIFT_VERSION = 3.0; 657 | TVOS_DEPLOYMENT_TARGET = 9.0; 658 | VERSIONING_SYSTEM = "apple-generic"; 659 | VERSION_INFO_PREFIX = ""; 660 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 661 | }; 662 | name = Debug; 663 | }; 664 | 65EAC4BB1D8C42170001F670 /* Release */ = { 665 | isa = XCBuildConfiguration; 666 | buildSettings = { 667 | APPLICATION_EXTENSION_API_ONLY = YES; 668 | CLANG_ANALYZER_NONNULL = YES; 669 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 670 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 671 | CODE_SIGN_IDENTITY = ""; 672 | COPY_PHASE_STRIP = NO; 673 | CURRENT_PROJECT_VERSION = 1; 674 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 675 | DEFINES_MODULE = YES; 676 | DEVELOPMENT_TEAM = ERA9S8SPNY; 677 | DYLIB_COMPATIBILITY_VERSION = 1; 678 | DYLIB_CURRENT_VERSION = 1; 679 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 680 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-iOS.plist"; 681 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 682 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 683 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 684 | MTL_ENABLE_DEBUG_INFO = NO; 685 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ImageHelper-iOS"; 686 | PRODUCT_NAME = ImageHelper; 687 | SKIP_INSTALL = YES; 688 | SWIFT_VERSION = 3.0; 689 | TVOS_DEPLOYMENT_TARGET = 9.0; 690 | VERSIONING_SYSTEM = "apple-generic"; 691 | VERSION_INFO_PREFIX = ""; 692 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 693 | }; 694 | name = Release; 695 | }; 696 | 65EAC4C81D8C42270001F670 /* Debug */ = { 697 | isa = XCBuildConfiguration; 698 | buildSettings = { 699 | APPLICATION_EXTENSION_API_ONLY = YES; 700 | CLANG_ANALYZER_NONNULL = YES; 701 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 702 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 703 | CODE_SIGN_IDENTITY = ""; 704 | CURRENT_PROJECT_VERSION = 1; 705 | DEBUG_INFORMATION_FORMAT = dwarf; 706 | DEFINES_MODULE = YES; 707 | DYLIB_COMPATIBILITY_VERSION = 1; 708 | DYLIB_CURRENT_VERSION = 1; 709 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 710 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-watchOS.plist"; 711 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 712 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 713 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 714 | MTL_ENABLE_DEBUG_INFO = YES; 715 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ImageHelper-watchOS"; 716 | PRODUCT_NAME = ImageHelper; 717 | SDKROOT = watchos; 718 | SKIP_INSTALL = YES; 719 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 720 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 721 | SWIFT_VERSION = 3.0; 722 | TARGETED_DEVICE_FAMILY = 4; 723 | TVOS_DEPLOYMENT_TARGET = 9.0; 724 | VERSIONING_SYSTEM = "apple-generic"; 725 | VERSION_INFO_PREFIX = ""; 726 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 727 | }; 728 | name = Debug; 729 | }; 730 | 65EAC4C91D8C42270001F670 /* Release */ = { 731 | isa = XCBuildConfiguration; 732 | buildSettings = { 733 | APPLICATION_EXTENSION_API_ONLY = YES; 734 | CLANG_ANALYZER_NONNULL = YES; 735 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 736 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 737 | CODE_SIGN_IDENTITY = ""; 738 | COPY_PHASE_STRIP = NO; 739 | CURRENT_PROJECT_VERSION = 1; 740 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 741 | DEFINES_MODULE = YES; 742 | DYLIB_COMPATIBILITY_VERSION = 1; 743 | DYLIB_CURRENT_VERSION = 1; 744 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 745 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-watchOS.plist"; 746 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 747 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 748 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 749 | MTL_ENABLE_DEBUG_INFO = NO; 750 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ImageHelper-watchOS"; 751 | PRODUCT_NAME = ImageHelper; 752 | SDKROOT = watchos; 753 | SKIP_INSTALL = YES; 754 | SWIFT_VERSION = 3.0; 755 | TARGETED_DEVICE_FAMILY = 4; 756 | TVOS_DEPLOYMENT_TARGET = 9.0; 757 | VERSIONING_SYSTEM = "apple-generic"; 758 | VERSION_INFO_PREFIX = ""; 759 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 760 | }; 761 | name = Release; 762 | }; 763 | 65EAC4D51D8C423D0001F670 /* Debug */ = { 764 | isa = XCBuildConfiguration; 765 | buildSettings = { 766 | APPLICATION_EXTENSION_API_ONLY = YES; 767 | CLANG_ANALYZER_NONNULL = YES; 768 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 769 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 770 | CODE_SIGN_IDENTITY = ""; 771 | CURRENT_PROJECT_VERSION = 1; 772 | DEBUG_INFORMATION_FORMAT = dwarf; 773 | DEFINES_MODULE = YES; 774 | DYLIB_COMPATIBILITY_VERSION = 1; 775 | DYLIB_CURRENT_VERSION = 1; 776 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 777 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-tvOS.plist"; 778 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 779 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 780 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 781 | MTL_ENABLE_DEBUG_INFO = YES; 782 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ImageHelper-tvOS"; 783 | PRODUCT_NAME = ImageHelper; 784 | SDKROOT = appletvos; 785 | SKIP_INSTALL = YES; 786 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 787 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 788 | SWIFT_VERSION = 3.0; 789 | TARGETED_DEVICE_FAMILY = 3; 790 | TVOS_DEPLOYMENT_TARGET = 9.0; 791 | VERSIONING_SYSTEM = "apple-generic"; 792 | VERSION_INFO_PREFIX = ""; 793 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 794 | }; 795 | name = Debug; 796 | }; 797 | 65EAC4D61D8C423D0001F670 /* Release */ = { 798 | isa = XCBuildConfiguration; 799 | buildSettings = { 800 | APPLICATION_EXTENSION_API_ONLY = YES; 801 | CLANG_ANALYZER_NONNULL = YES; 802 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 803 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 804 | CODE_SIGN_IDENTITY = ""; 805 | COPY_PHASE_STRIP = NO; 806 | CURRENT_PROJECT_VERSION = 1; 807 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 808 | DEFINES_MODULE = YES; 809 | DYLIB_COMPATIBILITY_VERSION = 1; 810 | DYLIB_CURRENT_VERSION = 1; 811 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 812 | INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-tvOS.plist"; 813 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 814 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 815 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 816 | MTL_ENABLE_DEBUG_INFO = NO; 817 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ImageHelper-tvOS"; 818 | PRODUCT_NAME = ImageHelper; 819 | SDKROOT = appletvos; 820 | SKIP_INSTALL = YES; 821 | SWIFT_VERSION = 3.0; 822 | TARGETED_DEVICE_FAMILY = 3; 823 | TVOS_DEPLOYMENT_TARGET = 9.0; 824 | VERSIONING_SYSTEM = "apple-generic"; 825 | VERSION_INFO_PREFIX = ""; 826 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 827 | }; 828 | name = Release; 829 | }; 830 | 65F5EC4A1D8C493C004A35E8 /* Debug */ = { 831 | isa = XCBuildConfiguration; 832 | buildSettings = { 833 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; 834 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 835 | CLANG_ANALYZER_NONNULL = YES; 836 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 837 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 838 | DEBUG_INFORMATION_FORMAT = dwarf; 839 | INFOPLIST_FILE = "Demo tvOS/Info.plist"; 840 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 841 | MTL_ENABLE_DEBUG_INFO = YES; 842 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ImageHelperDemo-tvOS"; 843 | PRODUCT_NAME = "$(TARGET_NAME)"; 844 | SDKROOT = appletvos; 845 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 846 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 847 | SWIFT_VERSION = 3.0; 848 | TARGETED_DEVICE_FAMILY = 3; 849 | TVOS_DEPLOYMENT_TARGET = 10.0; 850 | }; 851 | name = Debug; 852 | }; 853 | 65F5EC4B1D8C493C004A35E8 /* Release */ = { 854 | isa = XCBuildConfiguration; 855 | buildSettings = { 856 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; 857 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 858 | CLANG_ANALYZER_NONNULL = YES; 859 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 860 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 861 | COPY_PHASE_STRIP = NO; 862 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 863 | INFOPLIST_FILE = "Demo tvOS/Info.plist"; 864 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 865 | MTL_ENABLE_DEBUG_INFO = NO; 866 | PRODUCT_BUNDLE_IDENTIFIER = "com.allforces.ImageHelperDemo-tvOS"; 867 | PRODUCT_NAME = "$(TARGET_NAME)"; 868 | SDKROOT = appletvos; 869 | SWIFT_VERSION = 3.0; 870 | TARGETED_DEVICE_FAMILY = 3; 871 | TVOS_DEPLOYMENT_TARGET = 10.0; 872 | }; 873 | name = Release; 874 | }; 875 | /* End XCBuildConfiguration section */ 876 | 877 | /* Begin XCConfigurationList section */ 878 | 6561367A192E526900E30E76 /* Build configuration list for PBXProject "ImageHelper" */ = { 879 | isa = XCConfigurationList; 880 | buildConfigurations = ( 881 | 656136B2192E526900E30E76 /* Debug */, 882 | 656136B3192E526900E30E76 /* Release */, 883 | ); 884 | defaultConfigurationIsVisible = 0; 885 | defaultConfigurationName = Release; 886 | }; 887 | 6581F3EF1968328200C5CA28 /* Build configuration list for PBXNativeTarget "Demo iOS" */ = { 888 | isa = XCConfigurationList; 889 | buildConfigurations = ( 890 | 6581F3F01968328200C5CA28 /* Debug */, 891 | 6581F3F11968328200C5CA28 /* Release */, 892 | ); 893 | defaultConfigurationIsVisible = 0; 894 | defaultConfigurationName = Release; 895 | }; 896 | 65EAC4B91D8C42170001F670 /* Build configuration list for PBXNativeTarget "ImageHelper iOS" */ = { 897 | isa = XCConfigurationList; 898 | buildConfigurations = ( 899 | 65EAC4BA1D8C42170001F670 /* Debug */, 900 | 65EAC4BB1D8C42170001F670 /* Release */, 901 | ); 902 | defaultConfigurationIsVisible = 0; 903 | defaultConfigurationName = Release; 904 | }; 905 | 65EAC4C71D8C42270001F670 /* Build configuration list for PBXNativeTarget "ImageHelper watchOS" */ = { 906 | isa = XCConfigurationList; 907 | buildConfigurations = ( 908 | 65EAC4C81D8C42270001F670 /* Debug */, 909 | 65EAC4C91D8C42270001F670 /* Release */, 910 | ); 911 | defaultConfigurationIsVisible = 0; 912 | defaultConfigurationName = Release; 913 | }; 914 | 65EAC4D41D8C423D0001F670 /* Build configuration list for PBXNativeTarget "ImageHelper tvOS" */ = { 915 | isa = XCConfigurationList; 916 | buildConfigurations = ( 917 | 65EAC4D51D8C423D0001F670 /* Debug */, 918 | 65EAC4D61D8C423D0001F670 /* Release */, 919 | ); 920 | defaultConfigurationIsVisible = 0; 921 | defaultConfigurationName = Release; 922 | }; 923 | 65F5EC491D8C493C004A35E8 /* Build configuration list for PBXNativeTarget "Demo tvOS" */ = { 924 | isa = XCConfigurationList; 925 | buildConfigurations = ( 926 | 65F5EC4A1D8C493C004A35E8 /* Debug */, 927 | 65F5EC4B1D8C493C004A35E8 /* Release */, 928 | ); 929 | defaultConfigurationIsVisible = 0; 930 | defaultConfigurationName = Release; 931 | }; 932 | /* End XCConfigurationList section */ 933 | }; 934 | rootObject = 65613677192E526900E30E76 /* Project object */; 935 | } 936 | -------------------------------------------------------------------------------- /ImageHelper.xcodeproj/project.xcworkspace.folder/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ImageHelper.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ImageHelper.xcodeproj/xcshareddata/xcschemes/ImageHelper iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /ImageHelper.xcodeproj/xcshareddata/xcschemes/ImageHelper tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Melvin Rivera 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ImageHelper 2 | 3 | [![Version](https://img.shields.io/cocoapods/v/AFImageHelper.svg?style=flat)](http://cocoapods.org/pods/AFImageHelper) 4 | [![License](https://img.shields.io/cocoapods/l/AFImageHelper.svg?style=flat)](http://cocoapods.org/pods/AFImageHelper) 5 | [![Platform](https://img.shields.io/cocoapods/p/AFImageHelper.svg?style=flat)](http://cocoapods.org/pods/AFImageHelper) 6 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 7 | 8 | Image Extensions for Swift 3.0 9 | 10 | 11 | ![Sample Project Screenshot](https://raw.githubusercontent.com/melvitax/AFImageHelper/master/Screenshot.png?raw=true "Sample Project Screenshot") 12 | 13 | ## Usage 14 | 15 | To run the example project, clone or download the repo, and run. 16 | 17 | 18 | ## UIImageView Extension 19 | 20 | 21 | ### Image from a URL 22 | ```Swift 23 | // Fetches an image from a URL. If caching is set, it will be cached by NSCache for future queries. The cached image is returned if available, otherise the placeholder is set. When the image is returned, the closure gets called. 24 | func imageFromURL(url: String, placeholder: UIImage, fadeIn: Bool = true, closure: ((image: UIImage?) 25 | 26 | ``` 27 | 28 | ## UIImage Extension 29 | 30 | ### Colors 31 | ```Swift 32 | // Creates an image from a solid color 33 | UIImage(color:UIColor, size:CGSize) 34 | 35 | // Creates an image from a gradient color 36 | UIImage(gradientColors:[UIColor], size:CGSize) 37 | 38 | // Applies a gradient overlay to an image 39 | func applyGradientColors(gradientColors: [UIColor], blendMode: CGBlendMode) -> UIImage 40 | 41 | // Creates an image from a radial gradient 42 | UIImage(startColor: UIColor, endColor: UIColor, radialGradientCenter: CGPoint, radius:Float, size:CGSize) 43 | 44 | ``` 45 | 46 | ### Text 47 | ```Swift 48 | // Creates an image with a string of text 49 | UIImage(text: String, font: UIFont, color: UIColor, backgroundColor: UIColor, size:CGSize, offset: CGPoint) 50 | 51 | ``` 52 | 53 | ### Screenshot 54 | ```Swift 55 | // Creates an image from a UIView 56 | UIImage(fromView view: UIView) 57 | 58 | ``` 59 | 60 | 61 | ### Alpha and Padding 62 | ```Swift 63 | // Returns true if the image has an alpha layer 64 | func hasAlpha() -> Bool 65 | 66 | // Returns a copy(if needed) of the image with alpha layer 67 | func applyAlpha() -> UIImage? 68 | 69 | // Returns a copy of the image with a transparent border of the given size added around its edges 70 | func applyPadding(padding: CGFloat) -> UIImage? 71 | 72 | ``` 73 | 74 | ### Crop and Resize 75 | ```Swift 76 | // Crops an image to a new rect 77 | func crop(bounds: CGRect) -> UIImage? 78 | 79 | // Crops an image to a centered square 80 | func cropToSquare() -> UIImage? { 81 | 82 | // Resizes an image 83 | func resize(size:CGSize, contentMode: UIImageContentMode = .ScaleToFill) -> UIImage? 84 | 85 | ``` 86 | 87 | ### Circle and Rounded Corners 88 | ```Swift 89 | // Rounds corners of an image 90 | func roundCorners(cornerRadius:CGFloat) -> UIImage? 91 | 92 | // Rounds corners of an image with border 93 | func roundCorners(cornerRadius:CGFloat, border:CGFloat, color:UIColor) -> UIImage? 94 | 95 | // Rounds corners to a circle 96 | func roundCornersToCircle() -> UIImage? 97 | 98 | // Rounds corners to a circle with border 99 | func roundCornersToCircle(border border:CGFloat, color:UIColor) -> UIImage? 100 | 101 | ``` 102 | 103 | ### Border 104 | ```Swift 105 | // Adds a border 106 | func applyBorder(border:CGFloat, color:UIColor) -> UIImage? 107 | 108 | ``` 109 | 110 | ### Image Effects 111 | ```Swift 112 | // Applies a light blur effect to the image 113 | func applyLightEffect() -> UIImage? 114 | // Applies a extra light blur effect to the image 115 | func applyExtraLightEffect() -> UIImage? 116 | // Applies a dark blur effect to the image 117 | func applyDarkEffect() -> UIImage? 118 | // Applies a color tint to an image 119 | func applyTintEffect(tintColor: UIColor) -> UIImage? 120 | // Applies a blur to an image based on the specified radius, tint color saturation and mask image 121 | func applyBlur(blurRadius:CGFloat, tintColor:UIColor?, saturationDeltaFactor:CGFloat, maskImage:UIImage? = nil) -> UIImage? 122 | 123 | ``` 124 | 125 | ### Screen Density 126 | ```Swift 127 | // To create an image that is Retina aware, use the screen scale as a multiplier for your size. You should also use this technique for padding or borders. 128 | let width = 140 * UIScreen.mainScreen().scale 129 | let height = 140 * UIScreen.mainScreen().scale 130 | let image = UIImage(named: "myImage")?.resize(CGSize(width: width, height: height)) 131 | 132 | ``` 133 | -------------------------------------------------------------------------------- /Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/melvitax/ImageHelper/5dbb2547a33a1bbf4feff9a8f2bbd155ea26818d/Screenshot.png -------------------------------------------------------------------------------- /Sources/ImageHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // ImageHelper iOS.h 3 | // ImageHelper iOS 4 | // 5 | // Created by Melvin Rivera on 9/16/16. 6 | // Copyright © 2016 All Forces. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for ImageHelper iOS. 12 | FOUNDATION_EXPORT double ImageHelperVersionNumber; 13 | 14 | //! Project version string for ImageHelper iOS. 15 | FOUNDATION_EXPORT const unsigned char ImageHelperVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Sources/ImageHelper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageHelper.swift 3 | // 4 | // ImageHelper 5 | // Version 3.2.2 6 | // 7 | // Created by Melvin Rivera on 7/5/14. 8 | // Copyright (c) 2014 All Forces. All rights reserved. 9 | // 10 | 11 | import Foundation 12 | import UIKit 13 | import QuartzCore 14 | import CoreGraphics 15 | import Accelerate 16 | 17 | 18 | public enum UIImageContentMode { 19 | case scaleToFill, scaleAspectFit, scaleAspectFill 20 | } 21 | 22 | public extension UIImage { 23 | 24 | /** 25 | A singleton shared NSURL cache used for images from URL 26 | */ 27 | static var shared: NSCache! { 28 | struct StaticSharedCache { 29 | static var shared: NSCache? = NSCache() 30 | } 31 | 32 | return StaticSharedCache.shared! 33 | } 34 | 35 | // MARK: Image from solid color 36 | /** 37 | Creates a new solid color image. 38 | 39 | - Parameter color: The color to fill the image with. 40 | - Parameter size: Image size (defaults: 10x10) 41 | 42 | - Returns A new image 43 | */ 44 | convenience init?(color: UIColor, size: CGSize = CGSize(width: 10, height: 10)) { 45 | let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) 46 | UIGraphicsBeginImageContextWithOptions(rect.size, false, 0) 47 | 48 | let context = UIGraphicsGetCurrentContext() 49 | context?.setFillColor(color.cgColor) 50 | context?.fill(rect) 51 | 52 | self.init(cgImage:(UIGraphicsGetImageFromCurrentImageContext()?.cgImage!)!) 53 | UIGraphicsEndImageContext() 54 | } 55 | 56 | // MARK: Image from gradient colors 57 | /** 58 | Creates a gradient color image. 59 | 60 | - Parameter gradientColors: An array of colors to use for the gradient. 61 | - Parameter size: Image size (defaults: 10x10) 62 | 63 | - Returns A new image 64 | */ 65 | convenience init?(gradientColors:[UIColor], size:CGSize = CGSize(width: 10, height: 10), locations: [Float] = [] ) 66 | { 67 | UIGraphicsBeginImageContextWithOptions(size, false, 0) 68 | let context = UIGraphicsGetCurrentContext() 69 | 70 | let colorSpace = CGColorSpaceCreateDeviceRGB() 71 | let colors = gradientColors.map {(color: UIColor) -> AnyObject! in return color.cgColor as AnyObject! } as NSArray 72 | let gradient: CGGradient 73 | if locations.count > 0 { 74 | let cgLocations = locations.map { CGFloat($0) } 75 | gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: cgLocations)! 76 | } else { 77 | gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: nil)! 78 | } 79 | context!.drawLinearGradient(gradient, start: CGPoint(x: 0, y: 0), end: CGPoint(x: 0, y: size.height), options: CGGradientDrawingOptions(rawValue: 0)) 80 | self.init(cgImage:(UIGraphicsGetImageFromCurrentImageContext()?.cgImage!)!) 81 | UIGraphicsEndImageContext() 82 | } 83 | 84 | /** 85 | Applies gradient color overlay to an image. 86 | 87 | - Parameter gradientColors: An array of colors to use for the gradient. 88 | - Parameter locations: An array of locations to use for the gradient. 89 | - Parameter blendMode: The blending type to use. 90 | 91 | - Returns A new image 92 | */ 93 | func apply(gradientColors: [UIColor], locations: [Float] = [], blendMode: CGBlendMode = CGBlendMode.normal) -> UIImage 94 | { 95 | UIGraphicsBeginImageContextWithOptions(size, false, scale) 96 | let context = UIGraphicsGetCurrentContext() 97 | context?.translateBy(x: 0, y: size.height) 98 | context?.scaleBy(x: 1.0, y: -1.0) 99 | context?.setBlendMode(blendMode) 100 | let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) 101 | 102 | context?.draw(self.cgImage!, in: rect) 103 | // Create gradient 104 | let colorSpace = CGColorSpaceCreateDeviceRGB() 105 | let colors = gradientColors.map {(color: UIColor) -> AnyObject! in return color.cgColor as AnyObject! } as NSArray 106 | let gradient: CGGradient 107 | if locations.count > 0 { 108 | let cgLocations = locations.map { CGFloat($0) } 109 | gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: cgLocations)! 110 | } else { 111 | gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: nil)! 112 | } 113 | // Apply gradient 114 | context?.clip(to: rect, mask: self.cgImage!) 115 | context?.drawLinearGradient(gradient, start: CGPoint(x: 0, y: 0), end: CGPoint(x: 0, y: size.height), options: CGGradientDrawingOptions(rawValue: 0)) 116 | let image = UIGraphicsGetImageFromCurrentImageContext() 117 | UIGraphicsEndImageContext(); 118 | return image!; 119 | } 120 | 121 | // MARK: Image with Text 122 | /** 123 | Creates a text label image. 124 | 125 | - Parameter text: The text to use in the label. 126 | - Parameter font: The font (default: System font of size 18) 127 | - Parameter color: The text color (default: White) 128 | - Parameter backgroundColor: The background color (default:Gray). 129 | - Parameter size: Image size (default: 10x10) 130 | - Parameter offset: Center offset (default: 0x0) 131 | 132 | - Returns A new image 133 | */ 134 | convenience init?(text: String, font: UIFont = UIFont.systemFont(ofSize: 18), color: UIColor = UIColor.white, backgroundColor: UIColor = UIColor.gray, size: CGSize = CGSize(width: 100, height: 100), offset: CGPoint = CGPoint(x: 0, y: 0)) { 135 | let label = UILabel(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height)) 136 | label.font = font 137 | label.text = text 138 | label.textColor = color 139 | label.textAlignment = .center 140 | label.backgroundColor = backgroundColor 141 | 142 | let image = UIImage(fromView: label) 143 | UIGraphicsBeginImageContextWithOptions(size, false, 0) 144 | image?.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) 145 | 146 | self.init(cgImage:(UIGraphicsGetImageFromCurrentImageContext()?.cgImage!)!) 147 | UIGraphicsEndImageContext() 148 | } 149 | 150 | // MARK: Image from UIView 151 | /** 152 | Creates an image from a UIView. 153 | 154 | - Parameter fromView: The source view. 155 | 156 | - Returns A new image 157 | */ 158 | convenience init?(fromView view: UIView) { 159 | UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0) 160 | //view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true) 161 | view.layer.render(in: UIGraphicsGetCurrentContext()!) 162 | self.init(cgImage:(UIGraphicsGetImageFromCurrentImageContext()?.cgImage!)!) 163 | UIGraphicsEndImageContext() 164 | } 165 | 166 | // MARK: Image with Radial Gradient 167 | // Radial background originally from: http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_shadings/dq_shadings.html 168 | /** 169 | Creates a radial gradient. 170 | 171 | - Parameter startColor: The start color 172 | - Parameter endColor: The end color 173 | - Parameter radialGradientCenter: The gradient center (default:0.5,0.5). 174 | - Parameter radius: Radius size (default: 0.5) 175 | - Parameter size: Image size (default: 100x100) 176 | 177 | - Returns A new image 178 | */ 179 | convenience init?(startColor: UIColor, endColor: UIColor, radialGradientCenter: CGPoint = CGPoint(x: 0.5, y: 0.5), radius: Float = 0.5, size: CGSize = CGSize(width: 100, height: 100)) { 180 | UIGraphicsBeginImageContextWithOptions(size, true, 0) 181 | 182 | let num_locations: Int = 2 183 | let locations: [CGFloat] = [0.0, 1.0] as [CGFloat] 184 | 185 | let startComponents = startColor.cgColor.components! 186 | let endComponents = endColor.cgColor.components! 187 | 188 | let components: [CGFloat] = [startComponents[0], startComponents[1], startComponents[2], startComponents[3], endComponents[0], endComponents[1], endComponents[2], endComponents[3]] 189 | 190 | let colorSpace = CGColorSpaceCreateDeviceRGB() 191 | let gradient = CGGradient(colorSpace: colorSpace, colorComponents: components, locations: locations, count: num_locations) 192 | 193 | // Normalize the 0-1 ranged inputs to the width of the image 194 | let aCenter = CGPoint(x: radialGradientCenter.x * size.width, y: radialGradientCenter.y * size.height) 195 | let aRadius = CGFloat(min(size.width, size.height)) * CGFloat(radius) 196 | 197 | // Draw it 198 | UIGraphicsGetCurrentContext()?.drawRadialGradient(gradient!, startCenter: aCenter, startRadius: 0, endCenter: aCenter, endRadius: aRadius, options: CGGradientDrawingOptions.drawsAfterEndLocation) 199 | self.init(cgImage:(UIGraphicsGetImageFromCurrentImageContext()?.cgImage!)!) 200 | 201 | // Clean up 202 | UIGraphicsEndImageContext() 203 | } 204 | 205 | // MARK: Alpha 206 | /** 207 | Returns true if the image has an alpha layer. 208 | */ 209 | var hasAlpha: Bool { 210 | let alpha: CGImageAlphaInfo = self.cgImage!.alphaInfo 211 | switch alpha { 212 | case .first, .last, .premultipliedFirst, .premultipliedLast: 213 | return true 214 | default: 215 | return false 216 | } 217 | } 218 | 219 | /** 220 | Returns a copy of the given image, adding an alpha channel if it doesn't already have one. 221 | */ 222 | func applyAlpha() -> UIImage? { 223 | if hasAlpha { 224 | return self 225 | } 226 | 227 | let imageRef = self.cgImage; 228 | let width = imageRef?.width; 229 | let height = imageRef?.height; 230 | let colorSpace = imageRef?.colorSpace 231 | 232 | // The bitsPerComponent and bitmapInfo values are hard-coded to prevent an "unsupported parameter combination" error 233 | let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo().rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue) 234 | let offscreenContext = CGContext(data: nil, width: width!, height: height!, bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace!, bitmapInfo: bitmapInfo.rawValue) 235 | 236 | // Draw the image into the context and retrieve the new image, which will now have an alpha layer 237 | let rect: CGRect = CGRect(x: 0, y: 0, width: CGFloat(width!), height: CGFloat(height!)) 238 | offscreenContext?.draw(imageRef!, in: rect) 239 | let imageWithAlpha = UIImage(cgImage: (offscreenContext?.makeImage()!)!) 240 | return imageWithAlpha 241 | } 242 | 243 | /** 244 | Returns a copy of the image with a transparent border of the given size added around its edges. i.e. For rotating an image without getting jagged edges. 245 | 246 | - Parameter padding: The padding amount. 247 | 248 | - Returns A new image. 249 | */ 250 | func apply(padding: CGFloat) -> UIImage? { 251 | // If the image does not have an alpha layer, add one 252 | let image = self.applyAlpha() 253 | if image == nil { 254 | return nil 255 | } 256 | let rect = CGRect(x: 0, y: 0, width: size.width + padding * 2, height: size.height + padding * 2) 257 | 258 | // Build a context that's the same dimensions as the new size 259 | let colorSpace = self.cgImage?.colorSpace 260 | let bitmapInfo = self.cgImage?.bitmapInfo 261 | let bitsPerComponent = self.cgImage?.bitsPerComponent 262 | let context = CGContext(data: nil, width: Int(rect.size.width), height: Int(rect.size.height), bitsPerComponent: bitsPerComponent!, bytesPerRow: 0, space: colorSpace!, bitmapInfo: (bitmapInfo?.rawValue)!) 263 | 264 | // Draw the image in the center of the context, leaving a gap around the edges 265 | let imageLocation = CGRect(x: padding, y: padding, width: image!.size.width, height: image!.size.height) 266 | context?.draw(self.cgImage!, in: imageLocation) 267 | 268 | // Create a mask to make the border transparent, and combine it with the image 269 | let transparentImage = UIImage(cgImage: (context?.makeImage()?.masking(imageRef(withPadding: padding, size: rect.size))!)!) 270 | return transparentImage 271 | } 272 | 273 | /** 274 | Creates a mask that makes the outer edges transparent and everything else opaque. The size must include the entire mask (opaque part + transparent border). 275 | 276 | - Parameter padding: The padding amount. 277 | - Parameter size: The size of the image. 278 | 279 | - Returns A Core Graphics Image Ref 280 | */ 281 | fileprivate func imageRef(withPadding padding: CGFloat, size: CGSize) -> CGImage { 282 | // Build a context that's the same dimensions as the new size 283 | let colorSpace = CGColorSpaceCreateDeviceGray() 284 | let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo().rawValue | CGImageAlphaInfo.none.rawValue) 285 | let context = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: bitmapInfo.rawValue) 286 | 287 | // Start with a mask that's entirely transparent 288 | context?.setFillColor(UIColor.black.cgColor) 289 | context?.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height)) 290 | 291 | // Make the inner part (within the border) opaque 292 | context?.setFillColor(UIColor.white.cgColor) 293 | context?.fill(CGRect(x: padding, y: padding, width: size.width - padding * 2, height: size.height - padding * 2)) 294 | 295 | // Get an image of the context 296 | let maskImageRef = context?.makeImage() 297 | return maskImageRef! 298 | } 299 | 300 | 301 | // MARK: Crop 302 | 303 | /** 304 | Creates a cropped copy of an image. 305 | 306 | - Parameter bounds: The bounds of the rectangle inside the image. 307 | 308 | - Returns A new image 309 | */ 310 | func crop(bounds: CGRect) -> UIImage? { 311 | return UIImage(cgImage: (self.cgImage?.cropping(to: bounds)!)!, 312 | scale: 0.0, orientation: self.imageOrientation) 313 | } 314 | 315 | func cropToSquare() -> UIImage? { 316 | let size = CGSize(width: self.size.width * self.scale, height: self.size.height * self.scale) 317 | let shortest = min(size.width, size.height) 318 | 319 | let left: CGFloat = (size.width > shortest) ? (size.width - shortest) / 2 : 0 320 | let top: CGFloat = (size.height > shortest) ? (size.height - shortest) / 2 : 0 321 | 322 | let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) 323 | let insetRect = rect.insetBy(dx: left, dy: top) 324 | 325 | return crop(bounds: insetRect) 326 | } 327 | 328 | // MARK: Resize 329 | 330 | /** 331 | Creates a resized copy of an image. 332 | 333 | - Parameter size: The new size of the image. 334 | - Parameter contentMode: The way to handle the content in the new size. 335 | 336 | - Returns A new image 337 | */ 338 | func resize(toSize: CGSize, contentMode: UIImageContentMode = .scaleToFill) -> UIImage? { 339 | let horizontalRatio = size.width / self.size.width; 340 | let verticalRatio = size.height / self.size.height; 341 | var ratio: CGFloat! 342 | 343 | switch contentMode { 344 | case .scaleToFill: 345 | ratio = 1 346 | case .scaleAspectFill: 347 | ratio = max(horizontalRatio, verticalRatio) 348 | case .scaleAspectFit: 349 | ratio = min(horizontalRatio, verticalRatio) 350 | } 351 | 352 | let rect = CGRect(x: 0, y: 0, width: size.width * ratio, height: size.height * ratio) 353 | 354 | // Fix for a colorspace / transparency issue that affects some types of 355 | // images. See here: http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/comment-page-2/#comment-39951 356 | 357 | let colorSpace = CGColorSpaceCreateDeviceRGB() 358 | let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue) 359 | let context = CGContext(data: nil, width: Int(rect.size.width), height: Int(rect.size.height), bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: bitmapInfo.rawValue) 360 | 361 | let transform = CGAffineTransform.identity 362 | 363 | // Rotate and/or flip the image if required by its orientation 364 | context?.concatenate(transform); 365 | 366 | // Set the quality level to use when rescaling 367 | context!.interpolationQuality = CGInterpolationQuality(rawValue: 3)! 368 | 369 | //CGContextSetInterpolationQuality(context, CGInterpolationQuality(kCGInterpolationHigh.value)) 370 | 371 | // Draw into the context; this scales the image 372 | context?.draw(self.cgImage!, in: rect) 373 | 374 | // Get the resized image from the context and a UIImage 375 | let newImage = UIImage(cgImage: (context?.makeImage()!)!, scale: self.scale, orientation: self.imageOrientation) 376 | return newImage; 377 | } 378 | 379 | 380 | // MARK: Corner Radius 381 | 382 | /** 383 | Creates a new image with rounded corners. 384 | 385 | - Parameter cornerRadius: The corner radius. 386 | 387 | - Returns A new image 388 | */ 389 | func roundCorners(cornerRadius: CGFloat) -> UIImage? { 390 | // If the image does not have an alpha layer, add one 391 | let imageWithAlpha = applyAlpha() 392 | if imageWithAlpha == nil { 393 | return nil 394 | } 395 | 396 | UIGraphicsBeginImageContextWithOptions(size, false, 0) 397 | let width = imageWithAlpha?.cgImage?.width 398 | let height = imageWithAlpha?.cgImage?.height 399 | let bits = imageWithAlpha?.cgImage?.bitsPerComponent 400 | let colorSpace = imageWithAlpha?.cgImage?.colorSpace 401 | let bitmapInfo = imageWithAlpha?.cgImage?.bitmapInfo 402 | let context = CGContext(data: nil, width: width!, height: height!, bitsPerComponent: bits!, bytesPerRow: 0, space: colorSpace!, bitmapInfo: (bitmapInfo?.rawValue)!) 403 | let rect = CGRect(x: 0, y: 0, width: CGFloat(width!)*scale, height: CGFloat(height!)*scale) 404 | 405 | context?.beginPath() 406 | if (cornerRadius == 0) { 407 | context?.addRect(rect) 408 | } else { 409 | context?.saveGState() 410 | context?.translateBy(x: rect.minX, y: rect.minY) 411 | context?.scaleBy(x: cornerRadius, y: cornerRadius) 412 | let fw = rect.size.width / cornerRadius 413 | let fh = rect.size.height / cornerRadius 414 | context?.move(to: CGPoint(x: fw, y: fh/2)) 415 | context?.addArc(tangent1End: CGPoint(x: fw, y: fh), tangent2End: CGPoint(x: fw/2, y: fh), radius: 1) 416 | context?.addArc(tangent1End: CGPoint(x: 0, y: fh), tangent2End: CGPoint(x: 0, y: fh/2), radius: 1) 417 | context?.addArc(tangent1End: CGPoint(x: 0, y: 0), tangent2End: CGPoint(x: fw/2, y: 0), radius: 1) 418 | context?.addArc(tangent1End: CGPoint(x: fw, y: 0), tangent2End: CGPoint(x: fw, y: fh/2), radius: 1) 419 | context?.restoreGState() 420 | } 421 | context?.closePath() 422 | context?.clip() 423 | 424 | context?.draw(imageWithAlpha!.cgImage!, in: rect) 425 | let image = UIImage(cgImage: (context?.makeImage()!)!, scale:scale, orientation: .up) 426 | UIGraphicsEndImageContext() 427 | return image 428 | } 429 | 430 | /** 431 | Creates a new image with rounded corners and border. 432 | 433 | - Parameter cornerRadius: The corner radius. 434 | - Parameter border: The size of the border. 435 | - Parameter color: The color of the border. 436 | 437 | - Returns A new image 438 | */ 439 | func roundCorners(cornerRadius: CGFloat, border: CGFloat, color: UIColor) -> UIImage? { 440 | return roundCorners(cornerRadius: cornerRadius)?.apply(border: border, color: color) 441 | } 442 | 443 | /** 444 | Creates a new circle image. 445 | 446 | - Returns A new image 447 | */ 448 | func roundCornersToCircle() -> UIImage? { 449 | let shortest = min(size.width, size.height) 450 | return cropToSquare()?.roundCorners(cornerRadius: shortest/2) 451 | } 452 | 453 | /** 454 | Creates a new circle image with a border. 455 | 456 | - Parameter border :CGFloat The size of the border. 457 | - Parameter color :UIColor The color of the border. 458 | 459 | - Returns UIImage? 460 | */ 461 | func roundCornersToCircle(withBorder border: CGFloat, color: UIColor) -> UIImage? { 462 | let shortest = min(size.width, size.height) 463 | return cropToSquare()?.roundCorners(cornerRadius: shortest/2, border: border, color: color) 464 | } 465 | 466 | // MARK: Border 467 | 468 | /** 469 | Creates a new image with a border. 470 | 471 | - Parameter border: The size of the border. 472 | - Parameter color: The color of the border. 473 | 474 | - Returns A new image 475 | */ 476 | func apply(border: CGFloat, color: UIColor) -> UIImage? { 477 | UIGraphicsBeginImageContextWithOptions(size, false, 0) 478 | let width = self.cgImage?.width 479 | let height = self.cgImage?.height 480 | let bits = self.cgImage?.bitsPerComponent 481 | let colorSpace = self.cgImage?.colorSpace 482 | let bitmapInfo = self.cgImage?.bitmapInfo 483 | let context = CGContext(data: nil, width: width!, height: height!, bitsPerComponent: bits!, bytesPerRow: 0, space: colorSpace!, bitmapInfo: (bitmapInfo?.rawValue)!) 484 | var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0 485 | color.getRed(&red, green: &green, blue: &blue, alpha: &alpha) 486 | 487 | context?.setStrokeColor(red: red, green: green, blue: blue, alpha: alpha) 488 | context?.setLineWidth(border) 489 | 490 | let rect = CGRect(x: 0, y: 0, width: size.width*scale, height: size.height*scale) 491 | let inset = rect.insetBy(dx: border*scale, dy: border*scale) 492 | 493 | context?.strokeEllipse(in: inset) 494 | context?.draw(self.cgImage!, in: inset) 495 | 496 | let image = UIImage(cgImage: (context?.makeImage()!)!) 497 | UIGraphicsEndImageContext() 498 | 499 | return image 500 | } 501 | 502 | // MARK: Image Effects 503 | 504 | /** 505 | Applies a light blur effect to the image 506 | 507 | - Returns New image or nil 508 | */ 509 | func applyLightEffect() -> UIImage? { 510 | return applyBlur(withRadius: 30, tintColor: UIColor(white: 1.0, alpha: 0.3), saturationDeltaFactor: 1.8) 511 | } 512 | 513 | /** 514 | Applies a extra light blur effect to the image 515 | 516 | - Returns New image or nil 517 | */ 518 | func applyExtraLightEffect() -> UIImage? { 519 | return applyBlur(withRadius: 20, tintColor: UIColor(white: 0.97, alpha: 0.82), saturationDeltaFactor: 1.8) 520 | } 521 | 522 | /** 523 | Applies a dark blur effect to the image 524 | 525 | - Returns New image or nil 526 | */ 527 | func applyDarkEffect() -> UIImage? { 528 | return applyBlur(withRadius: 20, tintColor: UIColor(white: 0.11, alpha: 0.73), saturationDeltaFactor: 1.8) 529 | } 530 | 531 | /** 532 | Applies a color tint to an image 533 | 534 | - Parameter color: The tint color 535 | 536 | - Returns New image or nil 537 | */ 538 | func applyTintEffect(tintColor: UIColor) -> UIImage? { 539 | let effectColorAlpha: CGFloat = 0.6 540 | var effectColor = tintColor 541 | let componentCount = tintColor.cgColor.numberOfComponents 542 | if componentCount == 2 { 543 | var b: CGFloat = 0 544 | if tintColor.getWhite(&b, alpha: nil) { 545 | effectColor = UIColor(white: b, alpha: effectColorAlpha) 546 | } 547 | } else { 548 | var red: CGFloat = 0 549 | var green: CGFloat = 0 550 | var blue: CGFloat = 0 551 | 552 | if tintColor.getRed(&red, green: &green, blue: &blue, alpha: nil) { 553 | effectColor = UIColor(red: red, green: green, blue: blue, alpha: effectColorAlpha) 554 | } 555 | } 556 | return applyBlur(withRadius: 10, tintColor: effectColor, saturationDeltaFactor: -1.0) 557 | } 558 | 559 | /** 560 | Applies a blur to an image based on the specified radius, tint color saturation and mask image 561 | 562 | - Parameter blurRadius: The radius of the blur. 563 | - Parameter tintColor: The optional tint color. 564 | - Parameter saturationDeltaFactor: The detla for saturation. 565 | - Parameter maskImage: The optional image for masking. 566 | 567 | - Returns New image or nil 568 | */ 569 | func applyBlur(withRadius blurRadius: CGFloat, tintColor: UIColor?, saturationDeltaFactor: CGFloat, maskImage: UIImage? = nil) -> UIImage? { 570 | guard size.width > 0 && size.height > 0 && cgImage != nil else { 571 | return nil 572 | } 573 | if maskImage != nil { 574 | guard maskImage?.cgImage != nil else { 575 | return nil 576 | } 577 | } 578 | let imageRect = CGRect(origin: CGPoint.zero, size: size) 579 | var effectImage = self 580 | let hasBlur = blurRadius > CGFloat(FLT_EPSILON) 581 | let hasSaturationChange = fabs(saturationDeltaFactor - 1.0) > CGFloat(FLT_EPSILON) 582 | if (hasBlur || hasSaturationChange) { 583 | 584 | UIGraphicsBeginImageContextWithOptions(size, false, 0.0) 585 | let effectInContext = UIGraphicsGetCurrentContext() 586 | effectInContext?.scaleBy(x: 1.0, y: -1.0) 587 | effectInContext?.translateBy(x: 0, y: -size.height) 588 | effectInContext?.draw(cgImage!, in: imageRect) 589 | 590 | var effectInBuffer = vImage_Buffer( 591 | data: effectInContext?.data, 592 | height: UInt((effectInContext?.height)!), 593 | width: UInt((effectInContext?.width)!), 594 | rowBytes: (effectInContext?.bytesPerRow)!) 595 | 596 | UIGraphicsBeginImageContextWithOptions(size, false, 0.0); 597 | let effectOutContext = UIGraphicsGetCurrentContext() 598 | 599 | var effectOutBuffer = vImage_Buffer( 600 | data: effectOutContext?.data, 601 | height: UInt((effectOutContext?.height)!), 602 | width: UInt((effectOutContext?.width)!), 603 | rowBytes: (effectOutContext?.bytesPerRow)!) 604 | 605 | if hasBlur { 606 | let inputRadius = blurRadius * UIScreen.main.scale 607 | let sqrtPi: CGFloat = CGFloat(sqrt(M_PI * 2.0)) 608 | var radius = UInt32(floor(inputRadius * 3.0 * sqrtPi / 4.0 + 0.5)) 609 | if radius % 2 != 1 { 610 | radius += 1 // force radius to be odd so that the three box-blur methodology works. 611 | } 612 | let imageEdgeExtendFlags = vImage_Flags(kvImageEdgeExtend) 613 | vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, nil, 0, 0, radius, radius, nil, imageEdgeExtendFlags) 614 | vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, nil, 0, 0, radius, radius, nil, imageEdgeExtendFlags) 615 | vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, nil, 0, 0, radius, radius, nil, imageEdgeExtendFlags) 616 | } 617 | 618 | var effectImageBuffersAreSwapped = false 619 | 620 | if hasSaturationChange { 621 | let s: CGFloat = saturationDeltaFactor 622 | let floatingPointSaturationMatrix: [CGFloat] = [ 623 | 0.0722 + 0.9278 * s, 0.0722 - 0.0722 * s, 0.0722 - 0.0722 * s, 0, 624 | 0.7152 - 0.7152 * s, 0.7152 + 0.2848 * s, 0.7152 - 0.7152 * s, 0, 625 | 0.2126 - 0.2126 * s, 0.2126 - 0.2126 * s, 0.2126 + 0.7873 * s, 0, 626 | 0, 0, 0, 1 627 | ] 628 | 629 | let divisor: CGFloat = 256 630 | let matrixSize = floatingPointSaturationMatrix.count 631 | var saturationMatrix = [Int16](repeating: 0, count: matrixSize) 632 | 633 | for i: Int in 0 ..< matrixSize { 634 | saturationMatrix[i] = Int16(round(floatingPointSaturationMatrix[i] * divisor)) 635 | } 636 | 637 | if hasBlur { 638 | vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, Int32(divisor), nil, nil, vImage_Flags(kvImageNoFlags)) 639 | effectImageBuffersAreSwapped = true 640 | } else { 641 | vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, Int32(divisor), nil, nil, vImage_Flags(kvImageNoFlags)) 642 | } 643 | } 644 | 645 | if !effectImageBuffersAreSwapped { 646 | effectImage = UIGraphicsGetImageFromCurrentImageContext()! 647 | } 648 | 649 | UIGraphicsEndImageContext() 650 | 651 | if effectImageBuffersAreSwapped { 652 | effectImage = UIGraphicsGetImageFromCurrentImageContext()! 653 | } 654 | 655 | UIGraphicsEndImageContext() 656 | } 657 | 658 | // Set up output context. 659 | UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale) 660 | let outputContext = UIGraphicsGetCurrentContext() 661 | outputContext?.scaleBy(x: 1.0, y: -1.0) 662 | outputContext?.translateBy(x: 0, y: -size.height) 663 | 664 | // Draw base image. 665 | outputContext?.draw(self.cgImage!, in: imageRect) 666 | 667 | // Draw effect image. 668 | if hasBlur { 669 | outputContext?.saveGState() 670 | if let image = maskImage { 671 | outputContext?.clip(to: imageRect, mask: image.cgImage!); 672 | } 673 | outputContext?.draw(effectImage.cgImage!, in: imageRect) 674 | outputContext?.restoreGState() 675 | } 676 | 677 | // Add in color tint. 678 | if let color = tintColor { 679 | outputContext?.saveGState() 680 | outputContext?.setFillColor(color.cgColor) 681 | outputContext?.fill(imageRect) 682 | outputContext?.restoreGState() 683 | } 684 | 685 | // Output image is ready. 686 | let outputImage = UIGraphicsGetImageFromCurrentImageContext() 687 | UIGraphicsEndImageContext() 688 | 689 | return outputImage 690 | 691 | } 692 | 693 | 694 | // MARK: Image From URL 695 | 696 | /** 697 | Creates a new image from a URL with optional caching. If cached, the cached image is returned. Otherwise, a place holder is used until the image from web is returned by the closure. 698 | 699 | - Parameter url: The image URL. 700 | - Parameter placeholder: The placeholder image. 701 | - Parameter shouldCacheImage: Weather or not we should cache the NSURL response (default: true) 702 | - Parameter closure: Returns the image from the web the first time is fetched. 703 | 704 | - Returns A new image 705 | */ 706 | class func image(fromURL url: String, placeholder: UIImage, shouldCacheImage: Bool = true, closure: @escaping (_ image: UIImage?) -> ()) -> UIImage? { 707 | // From Cache 708 | if shouldCacheImage { 709 | if let image = UIImage.shared.object(forKey: url as AnyObject) as? UIImage { 710 | closure(nil) 711 | return image 712 | } 713 | } 714 | // Fetch Image 715 | let session = URLSession(configuration: URLSessionConfiguration.default) 716 | if let nsURL = URL(string: url) { 717 | session.dataTask(with: nsURL, completionHandler: { (data, response, error) -> Void in 718 | if (error != nil) { 719 | DispatchQueue.main.async { 720 | closure(nil) 721 | } 722 | } 723 | if let data = data, let image = UIImage(data: data) { 724 | if shouldCacheImage { 725 | UIImage.shared.setObject(image, forKey: url as AnyObject) 726 | } 727 | DispatchQueue.main.async { 728 | closure(image) 729 | } 730 | } 731 | session.finishTasksAndInvalidate() 732 | }).resume() 733 | } 734 | return placeholder 735 | } 736 | } 737 | -------------------------------------------------------------------------------- /Sources/ImageVIewExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageViewExtension.swift 3 | // 4 | // ImageHelper 5 | // Version 3.2.2 6 | // 7 | // Created by Melvin Rivera on 7/23/14. 8 | // Copyright (c) 2014 All Forces. All rights reserved. 9 | // 10 | 11 | import Foundation 12 | import UIKit 13 | import QuartzCore 14 | 15 | public extension UIImageView { 16 | 17 | /** 18 | Loads an image from a URL. If cached, the cached image is returned. Otherwise, a place holder is used until the image from web is returned by the closure. 19 | 20 | - Parameter url: The image URL. 21 | - Parameter placeholder: The placeholder image. 22 | - Parameter fadeIn: Weather the mage should fade in. 23 | - Parameter closure: Returns the image from the web the first time is fetched. 24 | 25 | - Returns A new image 26 | */ 27 | func imageFromURL(_ url: String, placeholder: UIImage, fadeIn: Bool = true, shouldCacheImage: Bool = true, closure: ((_ image: UIImage?) -> ())? = nil) 28 | { 29 | self.image = UIImage.image(fromURL: url, placeholder: placeholder, shouldCacheImage: shouldCacheImage) { 30 | (image: UIImage?) in 31 | if image == nil { 32 | return 33 | } 34 | self.image = image 35 | if fadeIn { 36 | let transition = CATransition() 37 | transition.duration = 0.5 38 | transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) 39 | transition.type = kCATransitionFade 40 | self.layer.add(transition, forKey: nil) 41 | } 42 | closure?(image) 43 | } 44 | } 45 | 46 | 47 | } 48 | 49 | -------------------------------------------------------------------------------- /Sources/Info-iOS.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Sources/Info-tvOS.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | --------------------------------------------------------------------------------