├── .DS_Store ├── Image Cache Resize ├── en.lproj │ ├── InfoPlist.strings │ └── MainStoryboard_iPhone.storyboard ├── .DS_Store ├── Default.png ├── Default@2x.png ├── Default-568h@2x.png ├── Libraries │ ├── .DS_Store │ ├── UIImage+Resize │ │ ├── UIImage+Scaling.h │ │ ├── UIImage+Alpha.h │ │ ├── UIImage+RoundedCorner.h │ │ ├── UIImage+Resize.h │ │ ├── UIImage+Scaling.m │ │ ├── UIImage+RoundedCorner.m │ │ ├── UIImage+Alpha.m │ │ └── UIImage+Resize.m │ └── SDWebImage │ │ ├── SDImageCacheDelegate.h │ │ ├── SDWebImageDownloaderDelegate.h │ │ ├── SDWebImagePrefetcher.h │ │ ├── SDWebImageDecoder.h │ │ ├── SDWebImageManagerDelegate.h │ │ ├── MKAnnotationView+WebCache.m │ │ ├── SDWebImageCompat.h │ │ ├── SDWebImageDownloader.h │ │ ├── SDWebImagePrefetcher.m │ │ ├── MKAnnotationView+WebCache.h │ │ ├── SDImageCache.h │ │ ├── SDWebImageDecoder.m │ │ ├── UIImageView+WebCache.m │ │ ├── UIButton+WebCache.m │ │ ├── SDWebImageManager.h │ │ ├── UIButton+WebCache.h │ │ ├── UIImageView+WebCache.h │ │ ├── SDWebImageDownloader.m │ │ ├── SDImageCache.m │ │ └── SDWebImageManager.m ├── AppDelegate.h ├── Image Cache Resize-Prefix.pch ├── main.m ├── ViewController.h ├── Image Cache Resize-Info.plist ├── AppDelegate.m └── ViewController.m ├── Image Cache Resize.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── toptier.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── xcdebugger │ │ └── Expressions.xcexplist ├── xcuserdata │ └── toptier.xcuserdatad │ │ ├── xcschemes │ │ ├── xcschememanagement.plist │ │ └── Image Cache Resize.xcscheme │ │ └── xcdebugger │ │ └── Breakpoints.xcbkptlist └── project.pbxproj └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toptierlabs/ImageCacheResize/HEAD/.DS_Store -------------------------------------------------------------------------------- /Image Cache Resize/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Image Cache Resize/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toptierlabs/ImageCacheResize/HEAD/Image Cache Resize/.DS_Store -------------------------------------------------------------------------------- /Image Cache Resize/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toptierlabs/ImageCacheResize/HEAD/Image Cache Resize/Default.png -------------------------------------------------------------------------------- /Image Cache Resize/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toptierlabs/ImageCacheResize/HEAD/Image Cache Resize/Default@2x.png -------------------------------------------------------------------------------- /Image Cache Resize/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toptierlabs/ImageCacheResize/HEAD/Image Cache Resize/Default-568h@2x.png -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toptierlabs/ImageCacheResize/HEAD/Image Cache Resize/Libraries/.DS_Store -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/UIImage+Resize/UIImage+Scaling.h: -------------------------------------------------------------------------------- 1 | @interface UIImage (Extras) 2 | - (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize; 3 | @end; -------------------------------------------------------------------------------- /Image Cache Resize.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Image Cache Resize.xcodeproj/project.xcworkspace/xcuserdata/toptier.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toptierlabs/ImageCacheResize/HEAD/Image Cache Resize.xcodeproj/project.xcworkspace/xcuserdata/toptier.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Image Cache Resize/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Image Cache Resize 4 | // 5 | // Created by TopTier on 10/26/12. 6 | // Copyright (c) 2012 TopTier. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Image Cache Resize/Image Cache Resize-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'Image Cache Resize' target in the 'Image Cache Resize' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_5_0 8 | #warning "This project uses features only available in iOS SDK 5.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Image Cache Resize/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Image Cache Resize 4 | // 5 | // Created by TopTier on 10/26/12. 6 | // Copyright (c) 2012 TopTier. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/UIImage+Resize/UIImage+Alpha.h: -------------------------------------------------------------------------------- 1 | // UIImage+Alpha.h 2 | // Created by Trevor Harmon on 9/20/09. 3 | // Free for personal or commercial use, with or without modification. 4 | // No warranty is expressed or implied. 5 | 6 | // Helper methods for adding an alpha layer to an image 7 | @interface UIImage (Alpha) 8 | - (BOOL)hasAlpha; 9 | - (UIImage *)imageWithAlpha; 10 | - (UIImage *)transparentBorderImage:(NSUInteger)borderSize; 11 | @end 12 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/UIImage+Resize/UIImage+RoundedCorner.h: -------------------------------------------------------------------------------- 1 | // UIImage+RoundedCorner.h 2 | // Created by Trevor Harmon on 9/20/09. 3 | // Free for personal or commercial use, with or without modification. 4 | // No warranty is expressed or implied. 5 | 6 | // Extends the UIImage class to support making rounded corners 7 | @interface UIImage (RoundedCorner) 8 | - (UIImage *)roundedCornerImage:(NSInteger)cornerSize borderSize:(NSInteger)borderSize; 9 | @end 10 | -------------------------------------------------------------------------------- /Image Cache Resize.xcodeproj/xcuserdata/toptier.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Image Cache Resize.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | AB2CD955163AE46A00EA290F 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Image Cache Resize/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // Image Cache Resize 4 | // 5 | // Created by TopTier on 10/26/12. 6 | // Copyright (c) 2012 TopTier. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController{ 12 | 13 | IBOutlet UIScrollView *scroller; 14 | 15 | IBOutlet UIImageView *image1; 16 | IBOutlet UIImageView *image2; 17 | IBOutlet UIImageView *image3; 18 | 19 | } 20 | 21 | @property(nonatomic, retain) UIScrollView *scroller; 22 | 23 | @property(nonatomic, retain) UIImageView *image1; 24 | @property(nonatomic, retain) UIImageView *image2; 25 | @property(nonatomic, retain) UIImageView *image3; 26 | 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/UIImage+Resize/UIImage+Resize.h: -------------------------------------------------------------------------------- 1 | // UIImage+Resize.h 2 | // Created by Trevor Harmon on 8/5/09. 3 | // Free for personal or commercial use, with or without modification. 4 | // No warranty is expressed or implied. 5 | 6 | // Extends the UIImage class to support resizing/cropping 7 | @interface UIImage (Resize) 8 | - (UIImage *)croppedImage:(CGRect)bounds; 9 | - (UIImage *)thumbnailImage:(NSInteger)thumbnailSize 10 | interpolationQuality:(CGInterpolationQuality)quality; 11 | - (UIImage *)resizedImage:(CGSize)newSize 12 | interpolationQuality:(CGInterpolationQuality)quality; 13 | - (UIImage *)resizedImageWithContentMode:(UIViewContentMode)contentMode 14 | bounds:(CGSize)bounds 15 | interpolationQuality:(CGInterpolationQuality)quality; 16 | @end -------------------------------------------------------------------------------- /Image Cache Resize.xcodeproj/project.xcworkspace/xcuserdata/toptier.xcuserdatad/xcdebugger/Expressions.xcexplist: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 10 | 11 | 13 | 14 | 15 | 16 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/SDImageCacheDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SDImageCacheDelegate.h 3 | // Dailymotion 4 | // 5 | // Created by Olivier Poitrey on 16/09/10. 6 | // Copyright 2010 Dailymotion. All rights reserved. 7 | // 8 | 9 | #import "SDWebImageCompat.h" 10 | 11 | @class SDImageCache; 12 | 13 | /** 14 | * Delegate protocol for SDImageCache 15 | */ 16 | @protocol SDImageCacheDelegate 17 | 18 | @optional 19 | 20 | /** 21 | * Called when [SDImageCache queryDiskCacheForKey:delegate:userInfo:] retrived the image from cache 22 | * 23 | * @param imageCache The cache store instance 24 | * @param image The requested image instance 25 | * @param key The requested image cache key 26 | * @param info The provided user info dictionary 27 | */ 28 | - (void)imageCache:(SDImageCache *)imageCache didFindImage:(UIImage *)image forKey:(NSString *)key userInfo:(NSDictionary *)info; 29 | 30 | /** 31 | * Called when [SDImageCache queryDiskCacheForKey:delegate:userInfo:] did not find the image in the cache 32 | * 33 | * @param imageCache The cache store instance 34 | * @param key The requested image cache key 35 | * @param info The provided user info dictionary 36 | */ 37 | - (void)imageCache:(SDImageCache *)imageCache didNotFindImageForKey:(NSString *)key userInfo:(NSDictionary *)info; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/SDWebImageDownloaderDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageCompat.h" 10 | 11 | @class SDWebImageDownloader; 12 | 13 | /** 14 | * Delegate protocol for SDWebImageDownloader 15 | */ 16 | @protocol SDWebImageDownloaderDelegate 17 | 18 | @optional 19 | 20 | - (void)imageDownloaderDidFinish:(SDWebImageDownloader *)downloader; 21 | 22 | /** 23 | * Called repeatedly while the image is downloading when [SDWebImageDownloader progressive] is enabled. 24 | * 25 | * @param downloader The SDWebImageDownloader instance 26 | * @param image The partial image representing the currently download portion of the image 27 | */ 28 | - (void)imageDownloader:(SDWebImageDownloader *)downloader didUpdatePartialImage:(UIImage *)image; 29 | 30 | /** 31 | * Called when download completed successfuly. 32 | * 33 | * @param downloader The SDWebImageDownloader instance 34 | * @param image The downloaded image object 35 | */ 36 | - (void)imageDownloader:(SDWebImageDownloader *)downloader didFinishWithImage:(UIImage *)image; 37 | 38 | /** 39 | * Called when an error occurred 40 | * 41 | * @param downloader The SDWebImageDownloader instance 42 | * @param error The error details 43 | */ 44 | - (void)imageDownloader:(SDWebImageDownloader *)downloader didFailWithError:(NSError *)error; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/SDWebImagePrefetcher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import 10 | #import "SDWebImageManagerDelegate.h" 11 | #import "SDWebImageManager.h" 12 | 13 | /** 14 | * Prefetch some URLs in the cache for future use. Images are downloaded in low priority. 15 | */ 16 | @interface SDWebImagePrefetcher : NSObject 17 | { 18 | NSArray *_prefetchURLs; 19 | NSUInteger _skippedCount; 20 | NSUInteger _finishedCount; 21 | NSUInteger _requestedCount; 22 | NSTimeInterval _startedTime; 23 | } 24 | 25 | /** 26 | * Maximum number of URLs to prefetch at the same time. Defaults to 3. 27 | */ 28 | @property (nonatomic, assign) NSUInteger maxConcurrentDownloads; 29 | 30 | /** 31 | * SDWebImageOptions for prefetcher. Defaults to SDWebImageLowPriority. 32 | */ 33 | @property (nonatomic, assign) SDWebImageOptions options; 34 | 35 | 36 | /** 37 | * Return the global image prefetcher instance. 38 | */ 39 | + (SDWebImagePrefetcher *)sharedImagePrefetcher; 40 | 41 | /** 42 | * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching, 43 | * currently one image is downloaded at a time, 44 | * and skips images for failed downloads and proceed to the next image in the list 45 | * 46 | * @param urls list of URLs to prefetch 47 | */ 48 | - (void)prefetchURLs:(NSArray *)urls; 49 | 50 | 51 | /** 52 | * Remove and cancel queued list 53 | */ 54 | - (void)cancelPrefetching; 55 | 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /Image Cache Resize/Image Cache Resize-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.toptierlabs.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | MainStoryboard_iPhone 29 | UIMainStoryboardFile~ipad 30 | MainStoryboard_iPad 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Image Cache Resize.xcodeproj/xcuserdata/toptier.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 18 | 19 | 31 | 32 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/UIImage+Resize/UIImage+Scaling.m: -------------------------------------------------------------------------------- 1 | @implementation UIImage (Extras) 2 | 3 | - (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize { 4 | 5 | UIImage *sourceImage = self; 6 | UIImage *newImage = nil; 7 | 8 | CGSize imageSize = sourceImage.size; 9 | CGFloat width = imageSize.width; 10 | CGFloat height = imageSize.height; 11 | 12 | CGFloat targetWidth = targetSize.width; 13 | CGFloat targetHeight = targetSize.height; 14 | 15 | CGFloat scaleFactor = 0.0; 16 | CGFloat scaledWidth = targetWidth; 17 | CGFloat scaledHeight = targetHeight; 18 | 19 | CGPoint thumbnailPoint = CGPointMake(0.0,0.0); 20 | 21 | if (CGSizeEqualToSize(imageSize, targetSize) == NO) { 22 | 23 | CGFloat widthFactor = targetWidth / width; 24 | CGFloat heightFactor = targetHeight / height; 25 | 26 | if (widthFactor < heightFactor) 27 | scaleFactor = widthFactor; 28 | else 29 | scaleFactor = heightFactor; 30 | 31 | scaledWidth = width * scaleFactor; 32 | scaledHeight = height * scaleFactor; 33 | 34 | // center the image 35 | 36 | if (widthFactor < heightFactor) { 37 | thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 38 | } else if (widthFactor > heightFactor) { 39 | thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; 40 | } 41 | } 42 | 43 | 44 | // this is actually the interesting part: 45 | 46 | UIGraphicsBeginImageContext(targetSize); 47 | 48 | CGRect thumbnailRect = CGRectZero; 49 | thumbnailRect.origin = thumbnailPoint; 50 | thumbnailRect.size.width = scaledWidth; 51 | thumbnailRect.size.height = scaledHeight; 52 | 53 | [sourceImage drawInRect:thumbnailRect]; 54 | 55 | newImage = UIGraphicsGetImageFromCurrentImageContext(); 56 | UIGraphicsEndImageContext(); 57 | 58 | if(newImage == nil) NSLog(@"could not scale image"); 59 | 60 | 61 | return newImage ; 62 | } 63 | 64 | @end; -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/SDWebImageDecoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * Created by james on 9/28/11. 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | #import 12 | #import "SDWebImageCompat.h" 13 | 14 | @protocol SDWebImageDecoderDelegate; 15 | 16 | /** 17 | * Decoding image data is the most expensive step, and it is performed on the main thread. SDWebImageDecoder force the 18 | * image decoding in a separate thread so UIImage will have high chance to reuse the cached result when used by UI in 19 | * the main thread. 20 | * 21 | * @see https://github.com/rs/SDWebImage/pull/18 22 | */ 23 | 24 | @interface SDWebImageDecoder : NSObject 25 | { 26 | NSOperationQueue *imageDecodingQueue; 27 | } 28 | 29 | /** 30 | * Returns a shared global instance of image decoder 31 | * 32 | * @return An SDWebImageDecoder shared instance 33 | */ 34 | + (SDWebImageDecoder *)sharedImageDecoder; 35 | 36 | /** 37 | * Pre-decode a given image in a separate thread. 38 | * 39 | * @param image The image to pre-decode 40 | * @param delegate The object to notify once pre-decoding is completed 41 | * @param info A user info object 42 | */ 43 | - (void)decodeImage:(UIImage *)image withDelegate:(id )delegate userInfo:(NSDictionary *)info; 44 | 45 | @end 46 | 47 | /** 48 | * Delegate protocol for SDWebImageDecoder 49 | */ 50 | @protocol SDWebImageDecoderDelegate 51 | 52 | /** 53 | * Called when pre-decoding is completed 54 | * 55 | * @param decoder The image decoder instance 56 | * @param image The pre-decoded image 57 | * @param userInfo the provided user info dictionary 58 | */ 59 | - (void)imageDecoder:(SDWebImageDecoder *)decoder didFinishDecodingImage:(UIImage *)image userInfo:(NSDictionary *)userInfo; 60 | 61 | @end 62 | 63 | @interface UIImage (ForceDecode) 64 | 65 | + (UIImage *)decodedImageWithImage:(UIImage *)image; 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Image Cache Resize/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Image Cache Resize 4 | // 5 | // Created by TopTier on 10/26/12. 6 | // Copyright (c) 2012 TopTier. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // 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. 22 | // 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. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // 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. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 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 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/SDWebImageManagerDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | @class SDWebImageManager; 10 | @class UIImage; 11 | 12 | /** 13 | * Delegate protocol for SDWebImageManager 14 | */ 15 | @protocol SDWebImageManagerDelegate 16 | 17 | @optional 18 | 19 | /** 20 | * Called while an image is downloading with an partial image object representing the currently downloaded portion of the image. 21 | * This delegate is called only if ImageIO is available and `SDWebImageProgressiveDownload` option has been used. 22 | * 23 | * @param imageManager The image manager 24 | * @param image The retrived image object 25 | * @param url The image URL used to retrive the image 26 | * @param info The user info dictionnary 27 | */ 28 | - (void)webImageManager:(SDWebImageManager *)imageManager didProgressWithPartialImage:(UIImage *)image forURL:(NSURL *)url userInfo:(NSDictionary *)info; 29 | - (void)webImageManager:(SDWebImageManager *)imageManager didProgressWithPartialImage:(UIImage *)image forURL:(NSURL *)url; 30 | 31 | /** 32 | * Called when image download is completed successfuly. 33 | * 34 | * @param imageManager The image manager 35 | * @param image The retrived image object 36 | * @param url The image URL used to retrive the image 37 | * @param info The user info dictionnary 38 | */ 39 | - (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image forURL:(NSURL *)url userInfo:(NSDictionary *)info; 40 | - (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image forURL:(NSURL *)url; 41 | - (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image; 42 | 43 | /** 44 | * Called when an error occurred. 45 | * 46 | * @param imageManager The image manager 47 | * @param error The error 48 | * @param url The image URL used to retrive the image 49 | * @param info The user info dictionnary 50 | */ 51 | - (void)webImageManager:(SDWebImageManager *)imageManager didFailWithError:(NSError *)error forURL:(NSURL *)url userInfo:(NSDictionary *)info; 52 | - (void)webImageManager:(SDWebImageManager *)imageManager didFailWithError:(NSError *)error forURL:(NSURL *)url; 53 | - (void)webImageManager:(SDWebImageManager *)imageManager didFailWithError:(NSError *)error; 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/MKAnnotationView+WebCache.m: -------------------------------------------------------------------------------- 1 | // 2 | // MKAnnotationView+WebCache.m 3 | // SDWebImage 4 | // 5 | // Created by Olivier Poitrey on 14/03/12. 6 | // Copyright (c) 2012 Dailymotion. All rights reserved. 7 | // 8 | 9 | #import "MKAnnotationView+WebCache.h" 10 | 11 | @implementation MKAnnotationView (WebCache) 12 | 13 | - (void)setImageWithURL:(NSURL *)url 14 | { 15 | [self setImageWithURL:url placeholderImage:nil]; 16 | } 17 | 18 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder 19 | { 20 | [self setImageWithURL:url placeholderImage:placeholder options:0]; 21 | } 22 | 23 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options 24 | { 25 | SDWebImageManager *manager = [SDWebImageManager sharedManager]; 26 | 27 | // Remove in progress downloader from queue 28 | [manager cancelForDelegate:self]; 29 | 30 | self.image = placeholder; 31 | 32 | if (url) 33 | { 34 | [manager downloadWithURL:url delegate:self options:options]; 35 | } 36 | } 37 | 38 | #if NS_BLOCKS_AVAILABLE 39 | - (void)setImageWithURL:(NSURL *)url success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 40 | { 41 | [self setImageWithURL:url placeholderImage:nil success:success failure:failure]; 42 | } 43 | 44 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 45 | { 46 | [self setImageWithURL:url placeholderImage:placeholder options:0 success:success failure:failure]; 47 | } 48 | 49 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 50 | { 51 | SDWebImageManager *manager = [SDWebImageManager sharedManager]; 52 | 53 | // Remove in progress downloader from queue 54 | [manager cancelForDelegate:self]; 55 | 56 | self.image = placeholder; 57 | 58 | if (url) 59 | { 60 | [manager downloadWithURL:url delegate:self options:options success:success failure:failure]; 61 | } 62 | } 63 | #endif 64 | 65 | - (void)cancelCurrentImageLoad 66 | { 67 | [[SDWebImageManager sharedManager] cancelForDelegate:self]; 68 | } 69 | 70 | - (void)webImageManager:(SDWebImageManager *)imageManager didProgressWithPartialImage:(UIImage *)image forURL:(NSURL *)url 71 | { 72 | self.image = image; 73 | } 74 | 75 | - (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image 76 | { 77 | self.image = image; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/SDWebImageCompat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * (c) Jamie Pinkham 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | #import 11 | 12 | #if !TARGET_OS_IPHONE 13 | #import 14 | #ifndef UIImage 15 | #define UIImage NSImage 16 | #endif 17 | #ifndef UIImageView 18 | #define UIImageView NSImageView 19 | #endif 20 | #else 21 | #import 22 | #endif 23 | 24 | #if ! __has_feature(objc_arc) 25 | #define SDWIAutorelease(__v) ([__v autorelease]); 26 | #define SDWIReturnAutoreleased SDWIAutorelease 27 | 28 | #define SDWIRetain(__v) ([__v retain]); 29 | #define SDWIReturnRetained SDWIRetain 30 | 31 | #define SDWIRelease(__v) ([__v release]); 32 | #define SDWISafeRelease(__v) ([__v release], __v = nil); 33 | #define SDWISuperDealoc [super dealloc]; 34 | 35 | #define SDWIWeak 36 | #else 37 | // -fobjc-arc 38 | #define SDWIAutorelease(__v) 39 | #define SDWIReturnAutoreleased(__v) (__v) 40 | 41 | #define SDWIRetain(__v) 42 | #define SDWIReturnRetained(__v) (__v) 43 | 44 | #define SDWIRelease(__v) 45 | #define SDWISafeRelease(__v) (__v = nil); 46 | #define SDWISuperDealoc 47 | 48 | #define SDWIWeak __unsafe_unretained 49 | #endif 50 | 51 | 52 | NS_INLINE UIImage *SDScaledImageForPath(NSString *path, NSObject *imageOrData) 53 | { 54 | if (!imageOrData) 55 | { 56 | return nil; 57 | } 58 | 59 | UIImage *image = nil; 60 | if ([imageOrData isKindOfClass:[NSData class]]) 61 | { 62 | image = [[UIImage alloc] initWithData:(NSData *)imageOrData]; 63 | } 64 | else if ([imageOrData isKindOfClass:[UIImage class]]) 65 | { 66 | image = SDWIReturnRetained((UIImage *)imageOrData); 67 | } 68 | else 69 | { 70 | return nil; 71 | } 72 | 73 | if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) 74 | { 75 | CGFloat scale = 1.0; 76 | if (path.length >= 8) 77 | { 78 | // Search @2x. at the end of the string, before a 3 to 4 extension length (only if key len is 8 or more @2x. + 4 len ext) 79 | NSRange range = [path rangeOfString:@"@2x." options:0 range:NSMakeRange(path.length - 8, 5)]; 80 | if (range.location != NSNotFound) 81 | { 82 | scale = 2.0; 83 | } 84 | } 85 | 86 | UIImage *scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:UIImageOrientationUp]; 87 | SDWISafeRelease(image) 88 | image = scaledImage; 89 | } 90 | 91 | return SDWIReturnAutoreleased(image); 92 | } 93 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/SDWebImageDownloader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import 10 | #import "SDWebImageDownloaderDelegate.h" 11 | #import "SDWebImageCompat.h" 12 | 13 | extern NSString *const SDWebImageDownloadStartNotification; 14 | extern NSString *const SDWebImageDownloadStopNotification; 15 | 16 | /** 17 | * Asynchronous downloader dedicated and optimized for image loading. 18 | */ 19 | @interface SDWebImageDownloader : NSObject 20 | { 21 | @private 22 | NSURL *url; 23 | SDWIWeak id delegate; 24 | NSURLConnection *connection; 25 | NSMutableData *imageData; 26 | id userInfo; 27 | BOOL lowPriority; 28 | NSUInteger expectedSize; 29 | BOOL progressive; 30 | size_t width, height; 31 | } 32 | 33 | @property (nonatomic, retain) NSURL *url; 34 | @property (nonatomic, assign) id delegate; 35 | @property (nonatomic, retain) NSMutableData *imageData; 36 | @property (nonatomic, retain) id userInfo; 37 | @property (nonatomic, readwrite) BOOL lowPriority; 38 | 39 | /** 40 | * If set to YES, enables progressive download support. 41 | * 42 | * The [SDWebImageDownloaderDelegate imageDownloader:didUpdatePartialImage:] delegate method is then called 43 | * while the image is downloaded with an image object containing the portion of the currently downloaded 44 | * image. 45 | * 46 | * @see http://www.cocoaintheshell.com/2011/05/progressive-images-download-imageio/ 47 | */ 48 | @property (nonatomic, readwrite) BOOL progressive; 49 | 50 | /** 51 | * Creates a SDWebImageDownloader async downloader instance with a given URL 52 | * 53 | * The delegate will be informed when the image is finish downloaded or an error has happen. 54 | * 55 | * @see SDWebImageDownloaderDelegate 56 | * 57 | * @param url The URL to the image to download 58 | * @param delegate The delegate object 59 | * @param userInfo A NSDictionary containing custom info 60 | * @param lowPriority Ensure the download won't run during UI interactions 61 | * 62 | * @return A new SDWebImageDownloader instance 63 | */ 64 | + (id)downloaderWithURL:(NSURL *)url delegate:(id)delegate userInfo:(id)userInfo lowPriority:(BOOL)lowPriority; 65 | + (id)downloaderWithURL:(NSURL *)url delegate:(id)delegate userInfo:(id)userInfo; 66 | + (id)downloaderWithURL:(NSURL *)url delegate:(id)delegate; 67 | 68 | - (void)start; 69 | 70 | /** 71 | * Cancel the download immediatelly 72 | */ 73 | - (void)cancel; 74 | 75 | // This method is now no-op and is deprecated 76 | + (void)setMaxConcurrentDownloads:(NSUInteger)max __attribute__((deprecated)); 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ImageCacheResize 2 | ========= 3 | 4 | This library integrates two existing works: 5 | 6 | - [SDWebImage](https://github.com/rs/SDWebImage): It is an excellent work that provides (Async image downloader, cache on memory, cache on disk, great performance). 7 | - [UIImage+Resize](https://github.com/coryalder/UIImage_Resize): By Trevor Harmon. Also, an improvement to this library is used. It is described [here](http://smallduck.wordpress.com/2010/01/14/improvement-to-uiimageplusresize-m/). The original post describing image scaling, resizing and cropping is [http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/](http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/). 8 | 9 | 10 | The project is a single view iOS project that shows some of the transformations that can be done. Specially one of them is very useful and hard to achieve using remote images: When the developer wants to show a remote image that need to be shown with a specific width and height but must preserve the aspect ratio. The solution is something described by Trevor, which is to shrink the content just enough to fit the smaller dimension within the view. Some parts of the images are cropped and the dimensions of the UIImageView can be anticipated. In order to achieve this effect the dimensions of the original file should be known (which can be done by reading the first bytes of data, there several posts about this on StackOverflow). 11 | 12 | 13 | New methods 14 | ---------- 15 | New methods were added to UIImageView (additionally to the methods added by the original SDWebImage version). 16 | 17 | ```objective-c 18 | 19 | - (void)setImageWithURL:(NSURL *)url andCropToBounds:(CGRect)bounds; 20 | 21 | - (void)setImageWithURL:(NSURL *)url andResize:(CGSize)size withContentMode:(UIViewContentMode)mode; 22 | 23 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder andCropToBounds:(CGRect)bounds; 24 | 25 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options andResize:(CGSize)size; 26 | 27 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options andResize:(CGSize)size withContentMode:(UIViewContentMode)mode; 28 | 29 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options andCropToBounds:(CGRect)bounds; 30 | 31 | ``` 32 | 33 | How to integrate into your project 34 | ---------- 35 | 36 | - Copy SDWebImage and UIImage+Resize folders content to your project. 37 | - Add the frameworks ImageIO.framework and MapKit.framework 38 | - Import UIImageView+WebCache.h. 39 | 40 | 41 | How to use 42 | ---------- 43 | Here are some examples using images in google: 44 | 45 | ```objective-c 46 | 47 | [imageview setImageWithURL:[NSURL URLWithString:@"http://t0.gstatic.com/images?q=tbn:ANd9GcQfraHpiabjEY8iDdBe9OUQYHMtwfuAv9ZRR0RYKuoVF_EpE8Fp5A"] andResize:CGSizeMake(30, 30) withContentMode:UIViewContentModeScaleAspectFit]; 48 | 49 | 50 | [imageview setImageWithURL:[NSURL URLWithString:@"http://t0.gstatic.com/images?q=tbn:ANd9GcQfraHpiabjEY8iDdBe9OUQYHMtwfuAv9ZRR0RYKuoVF_EpE8Fp5A"] andCropToBounds:CGRectMake(0, 0, 100, 100)]; 51 | 52 | ``` 53 | 54 | 55 | This project include some examples. Just clone and execute it. 56 | 57 | 58 | [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/toptierlabs/imagecacheresize/trend.png)](https://bitdeli.com/free "Bitdeli Badge") 59 | 60 | -------------------------------------------------------------------------------- /Image Cache Resize/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // Image Cache Resize 4 | // 5 | // Created by TopTier on 10/26/12. 6 | // Copyright (c) 2012 TopTier. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "UIImageView+WebCache.h" 11 | 12 | @interface ViewController () 13 | -(CGSize) SizeForCrop: (float) image_width 14 | imageHeight:(float) image_height 15 | containerWidth: (float)container_width 16 | containerHeight: (float) container_width; 17 | @end 18 | 19 | @implementation ViewController 20 | @synthesize scroller, image1, image2, image3; 21 | 22 | -(CGSize) SizeForCrop: (float) image_width 23 | imageHeight:(float) image_height 24 | containerWidth: (float)container_width 25 | containerHeight: (float) container_height{ 26 | 27 | float container_ratio = container_height/ container_width; 28 | float image_ratio = image_height/ image_width; 29 | float crop_width, crop_height; 30 | 31 | if (container_ratio < image_ratio) 32 | { 33 | // Crop height 34 | crop_width = image_width; 35 | crop_height = image_width * container_ratio; 36 | 37 | /* 38 | if (image_width / image_ratio > image_height) 39 | { 40 | // crop width 41 | crop_height = image_height; 42 | crop_width = image_height / image_ratio; 43 | } 44 | else 45 | { 46 | // crop height 47 | crop_width = image_width;; 48 | crop_height = image_width / image_ratio; 49 | 50 | }*/ 51 | } 52 | else 53 | { 54 | crop_height = image_height; 55 | crop_width = image_height / container_ratio; 56 | /*if (image_width / image_ratio > image_height) 57 | { 58 | // crop width 59 | crop_height = image_height; 60 | crop_width = image_height / image_ratio; 61 | } 62 | else 63 | { 64 | // crop height 65 | crop_width = image_width;; 66 | crop_height = image_width * image_ratio; 67 | 68 | }*/ 69 | } 70 | 71 | return CGSizeMake(crop_width, crop_height); 72 | } 73 | 74 | - (void)viewDidLoad 75 | { 76 | [super viewDidLoad]; 77 | // Do any additional setup after loading the view, typically from a nib. 78 | 79 | 80 | [scroller setContentSize:CGSizeMake(320, 2000)]; 81 | 82 | [image2 setImageWithURL:[NSURL URLWithString:@"http://t0.gstatic.com/images?q=tbn:ANd9GcQfraHpiabjEY8iDdBe9OUQYHMtwfuAv9ZRR0RYKuoVF_EpE8Fp5A"] andResize:CGSizeMake(30, 30) withContentMode:UIViewContentModeScaleAspectFit]; 83 | [image3 setImageWithURL:[NSURL URLWithString:@"http://t0.gstatic.com/images?q=tbn:ANd9GcQfraHpiabjEY8iDdBe9OUQYHMtwfuAv9ZRR0RYKuoVF_EpE8Fp5A"]]; 84 | 85 | 86 | 87 | float image_width = 300; 88 | float image_height = 168; 89 | 90 | float container_width = 119; 91 | float container_height = 112; 92 | 93 | CGSize cropsize = [self SizeForCrop:image_width imageHeight:image_height containerWidth:container_width containerHeight:container_height]; 94 | 95 | [image1 setImageWithURL:[NSURL URLWithString:@"http://t0.gstatic.com/images?q=tbn:ANd9GcQfraHpiabjEY8iDdBe9OUQYHMtwfuAv9ZRR0RYKuoVF_EpE8Fp5A"] andCropToBounds:CGRectMake(0, 0, cropsize.width, cropsize.height)]; 96 | 97 | 98 | } 99 | 100 | - (void)didReceiveMemoryWarning 101 | { 102 | [super didReceiveMemoryWarning]; 103 | // Dispose of any resources that can be recreated. 104 | } 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /Image Cache Resize.xcodeproj/xcuserdata/toptier.xcuserdatad/xcschemes/Image Cache Resize.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/SDWebImagePrefetcher.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImagePrefetcher.h" 10 | #import "SDWebImageManager.h" 11 | 12 | @interface SDWebImagePrefetcher () 13 | @property (nonatomic, retain) NSArray *prefetchURLs; 14 | @end 15 | 16 | @implementation SDWebImagePrefetcher 17 | 18 | static SDWebImagePrefetcher *instance; 19 | 20 | @synthesize prefetchURLs; 21 | @synthesize maxConcurrentDownloads; 22 | @synthesize options; 23 | 24 | + (SDWebImagePrefetcher *)sharedImagePrefetcher 25 | { 26 | if (instance == nil) 27 | { 28 | instance = [[SDWebImagePrefetcher alloc] init]; 29 | instance.maxConcurrentDownloads = 3; 30 | instance.options = (SDWebImageLowPriority); 31 | } 32 | 33 | return instance; 34 | } 35 | 36 | - (void)startPrefetchingAtIndex:(NSUInteger)index withManager:(SDWebImageManager *)imageManager 37 | { 38 | if (index >= [self.prefetchURLs count]) return; 39 | _requestedCount++; 40 | [imageManager downloadWithURL:[self.prefetchURLs objectAtIndex:index] delegate:self options:self.options]; 41 | } 42 | 43 | - (void)reportStatus 44 | { 45 | NSUInteger total = [self.prefetchURLs count]; 46 | NSLog(@"Finished prefetching (%d successful, %d skipped, timeElasped %.2f)", total - _skippedCount, _skippedCount, CFAbsoluteTimeGetCurrent() - _startedTime); 47 | } 48 | 49 | - (void)prefetchURLs:(NSArray *)urls 50 | { 51 | [self cancelPrefetching]; // Prevent duplicate prefetch request 52 | _startedTime = CFAbsoluteTimeGetCurrent(); 53 | self.prefetchURLs = urls; 54 | 55 | // Starts prefetching from the very first image on the list with the max allowed concurrency 56 | NSUInteger listCount = [self.prefetchURLs count]; 57 | SDWebImageManager *manager = [SDWebImageManager sharedManager]; 58 | for (NSUInteger i = 0; i < self.maxConcurrentDownloads && _requestedCount < listCount; i++) 59 | { 60 | [self startPrefetchingAtIndex:i withManager:manager]; 61 | } 62 | } 63 | 64 | - (void)cancelPrefetching 65 | { 66 | self.prefetchURLs = nil; 67 | _skippedCount = 0; 68 | _requestedCount = 0; 69 | _finishedCount = 0; 70 | [[SDWebImageManager sharedManager] cancelForDelegate:self]; 71 | } 72 | 73 | #pragma mark SDWebImagePrefetcher (SDWebImageManagerDelegate) 74 | 75 | - (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image 76 | { 77 | _finishedCount++; 78 | NSLog(@"Prefetched %d out of %d", _finishedCount, [self.prefetchURLs count]); 79 | 80 | if ([self.prefetchURLs count] > _requestedCount) 81 | { 82 | [self startPrefetchingAtIndex:_requestedCount withManager:imageManager]; 83 | } 84 | else if (_finishedCount == _requestedCount) 85 | { 86 | [self reportStatus]; 87 | } 88 | } 89 | 90 | - (void)webImageManager:(SDWebImageManager *)imageManager didFailWithError:(NSError *)error 91 | { 92 | _finishedCount++; 93 | NSLog(@"Prefetched %d out of %d (Failed)", _finishedCount, [self.prefetchURLs count]); 94 | 95 | // Add last failed 96 | _skippedCount++; 97 | 98 | if ([self.prefetchURLs count] > _requestedCount) 99 | { 100 | [self startPrefetchingAtIndex:_requestedCount withManager:imageManager]; 101 | } 102 | else if (_finishedCount == _requestedCount) 103 | { 104 | [self reportStatus]; 105 | } 106 | } 107 | 108 | - (void)dealloc 109 | { 110 | self.prefetchURLs = nil; 111 | SDWISuperDealoc; 112 | } 113 | 114 | @end 115 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/UIImage+Resize/UIImage+RoundedCorner.m: -------------------------------------------------------------------------------- 1 | // UIImage+RoundedCorner.m 2 | // Created by Trevor Harmon on 9/20/09. 3 | // Free for personal or commercial use, with or without modification. 4 | // No warranty is expressed or implied. 5 | 6 | #import "UIImage+RoundedCorner.h" 7 | #import "UIImage+Alpha.h" 8 | 9 | // Private helper methods 10 | @interface UIImage () 11 | - (void)addRoundedRectToPath:(CGRect)rect context:(CGContextRef)context ovalWidth:(CGFloat)ovalWidth ovalHeight:(CGFloat)ovalHeight; 12 | @end 13 | 14 | @implementation UIImage (RoundedCorner) 15 | 16 | // Creates a copy of this image with rounded corners 17 | // If borderSize is non-zero, a transparent border of the given size will also be added 18 | // Original author: Björn Sållarp. Used with permission. See: http://blog.sallarp.com/iphone-uiimage-round-corners/ 19 | - (UIImage *)roundedCornerImage:(NSInteger)cornerSize borderSize:(NSInteger)borderSize { 20 | // If the image does not have an alpha layer, add one 21 | UIImage *image = [self imageWithAlpha]; 22 | 23 | // Build a context that's the same dimensions as the new size 24 | CGContextRef context = CGBitmapContextCreate(NULL, 25 | image.size.width, 26 | image.size.height, 27 | CGImageGetBitsPerComponent(image.CGImage), 28 | 0, 29 | CGImageGetColorSpace(image.CGImage), 30 | CGImageGetBitmapInfo(image.CGImage)); 31 | 32 | // Create a clipping path with rounded corners 33 | CGContextBeginPath(context); 34 | [self addRoundedRectToPath:CGRectMake(borderSize, borderSize, image.size.width - borderSize * 2, image.size.height - borderSize * 2) 35 | context:context 36 | ovalWidth:cornerSize 37 | ovalHeight:cornerSize]; 38 | CGContextClosePath(context); 39 | CGContextClip(context); 40 | 41 | // Draw the image to the context; the clipping path will make anything outside the rounded rect transparent 42 | CGContextDrawImage(context, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage); 43 | 44 | // Create a CGImage from the context 45 | CGImageRef clippedImage = CGBitmapContextCreateImage(context); 46 | CGContextRelease(context); 47 | 48 | // Create a UIImage from the CGImage 49 | UIImage *roundedImage = [UIImage imageWithCGImage:clippedImage]; 50 | CGImageRelease(clippedImage); 51 | 52 | return roundedImage; 53 | } 54 | 55 | #pragma mark - 56 | #pragma mark Private helper methods 57 | 58 | // Adds a rectangular path to the given context and rounds its corners by the given extents 59 | // Original author: Björn Sållarp. Used with permission. See: http://blog.sallarp.com/iphone-uiimage-round-corners/ 60 | - (void)addRoundedRectToPath:(CGRect)rect context:(CGContextRef)context ovalWidth:(CGFloat)ovalWidth ovalHeight:(CGFloat)ovalHeight { 61 | if (ovalWidth == 0 || ovalHeight == 0) { 62 | CGContextAddRect(context, rect); 63 | return; 64 | } 65 | CGContextSaveGState(context); 66 | CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect)); 67 | CGContextScaleCTM(context, ovalWidth, ovalHeight); 68 | CGFloat fw = CGRectGetWidth(rect) / ovalWidth; 69 | CGFloat fh = CGRectGetHeight(rect) / ovalHeight; 70 | CGContextMoveToPoint(context, fw, fh/2); 71 | CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1); 72 | CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1); 73 | CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1); 74 | CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); 75 | CGContextClosePath(context); 76 | CGContextRestoreGState(context); 77 | } 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/MKAnnotationView+WebCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // MKAnnotationView+WebCache.h 3 | // SDWebImage 4 | // 5 | // Created by Olivier Poitrey on 14/03/12. 6 | // Copyright (c) 2012 Dailymotion. All rights reserved. 7 | // 8 | 9 | #import "MapKit/MapKit.h" 10 | #import "SDWebImageCompat.h" 11 | #import "SDWebImageManagerDelegate.h" 12 | #import "SDWebImageManager.h" 13 | 14 | /** 15 | * Integrates SDWebImage async downloading and caching of remote images with MKAnnotationView. 16 | */ 17 | @interface MKAnnotationView (WebCache) 18 | 19 | /** 20 | * Set the imageView `image` with an `url`. 21 | * 22 | * The downloand is asynchronous and cached. 23 | * 24 | * @param url The url for the image. 25 | */ 26 | - (void)setImageWithURL:(NSURL *)url; 27 | 28 | /** 29 | * Set the imageView `image` with an `url` and a placeholder. 30 | * 31 | * The downloand is asynchronous and cached. 32 | * 33 | * @param url The url for the image. 34 | * @param placeholder The image to be set initially, until the image request finishes. 35 | * @see setImageWithURL:placeholderImage:options: 36 | */ 37 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; 38 | 39 | /** 40 | * Set the imageView `image` with an `url`, placeholder and custom options. 41 | * 42 | * The downloand is asynchronous and cached. 43 | * 44 | * @param url The url for the image. 45 | * @param placeholder The image to be set initially, until the image request finishes. 46 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 47 | */ 48 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; 49 | 50 | #if NS_BLOCKS_AVAILABLE 51 | /** 52 | * Set the imageView `image` with an `url`. 53 | * 54 | * The downloand is asynchronous and cached. 55 | * 56 | * @param url The url for the image. 57 | * @param success A block to be executed when the image request succeed This block has no return value and takes a Boolean as parameter indicating if the image was cached or not. 58 | * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). 59 | */ 60 | - (void)setImageWithURL:(NSURL *)url success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 61 | 62 | /** 63 | * Set the imageView `image` with an `url`, placeholder. 64 | * 65 | * The downloand is asynchronous and cached. 66 | * 67 | * @param url The url for the image. 68 | * @param placeholder The image to be set initially, until the image request finishes. 69 | * @param success A block to be executed when the image request succeed This block has no return value and takes a Boolean as parameter indicating if the image was cached or not. 70 | * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). 71 | */ 72 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 73 | 74 | /** 75 | * Set the imageView `image` with an `url`, placeholder and custom options. 76 | * 77 | * The downloand is asynchronous and cached. 78 | * 79 | * @param url The url for the image. 80 | * @param placeholder The image to be set initially, until the image request finishes. 81 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 82 | * @param success A block to be executed when the image request succeed This block has no return value and takes a Boolean as parameter indicating if the image was cached or not. 83 | * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). 84 | */ 85 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 86 | #endif 87 | 88 | /** 89 | * Cancel the current download 90 | */ 91 | - (void)cancelCurrentImageLoad; 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/SDImageCache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import 10 | #import "SDImageCacheDelegate.h" 11 | 12 | /** 13 | * SDImageCache maintains a memory cache and an optional disk cache. Disk cache write operations are performed 14 | * asynchronous so it doesn’t add unnecessary latency to the UI. 15 | */ 16 | @interface SDImageCache : NSObject 17 | { 18 | NSMutableDictionary *memCache; 19 | NSString *diskCachePath; 20 | NSOperationQueue *cacheInQueue, *cacheOutQueue; 21 | } 22 | 23 | /** 24 | * Returns global shared cache instance 25 | * 26 | * @return SDImageCache global instance 27 | */ 28 | + (SDImageCache *)sharedImageCache; 29 | 30 | /** 31 | * Sets the global maximum cache age 32 | * 33 | * @param maxCacheAge The maximum length of time to keep an image in the cache, in seconds 34 | */ 35 | + (void) setMaxCacheAge:(NSInteger) maxCacheAge; 36 | 37 | /** 38 | * Store an image into memory and disk cache at the given key. 39 | * 40 | * @param image The image to store 41 | * @param key The unique image cache key, usually it's image absolute URL 42 | */ 43 | - (void)storeImage:(UIImage *)image forKey:(NSString *)key; 44 | 45 | /** 46 | * Store an image into memory and optionally disk cache at the given key. 47 | * 48 | * @param image The image to store 49 | * @param key The unique image cache key, usually it's image absolute URL 50 | * @param toDisk Store the image to disk cache if YES 51 | */ 52 | - (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk; 53 | 54 | /** 55 | * Store an image into memory and optionally disk cache at the given key. 56 | * 57 | * @param image The image to store 58 | * @param data The image data as returned by the server, this representation will be used for disk storage 59 | * instead of converting the given image object into a storable/compressed image format in order 60 | * to save quality and CPU 61 | * @param key The unique image cache key, usually it's image absolute URL 62 | * @param toDisk Store the image to disk cache if YES 63 | */ 64 | - (void)storeImage:(UIImage *)image imageData:(NSData *)data forKey:(NSString *)key toDisk:(BOOL)toDisk; 65 | 66 | /** 67 | * Query the memory cache for an image at a given key and fallback to disk cache 68 | * synchronousely if not found in memory. 69 | * 70 | * @warning This method may perform some synchronous IO operations 71 | * 72 | * @param key The unique key used to store the wanted image 73 | */ 74 | - (UIImage *)imageFromKey:(NSString *)key; 75 | 76 | /** 77 | * Query the memory cache for an image at a given key and optionnaly fallback to disk cache 78 | * synchronousely if not found in memory. 79 | * 80 | * @warning This method may perform some synchronous IO operations if fromDisk is YES 81 | * 82 | * @param key The unique key used to store the wanted image 83 | * @param fromDisk Try to retrive the image from disk if not found in memory if YES 84 | */ 85 | - (UIImage *)imageFromKey:(NSString *)key fromDisk:(BOOL)fromDisk; 86 | 87 | 88 | /** 89 | * Query the disk cache asynchronousely. 90 | * 91 | * @param key The unique key used to store the wanted image 92 | * @param delegate The delegate object to send response to 93 | * @param info An NSDictionary with some user info sent back to the delegate 94 | */ 95 | - (void)queryDiskCacheForKey:(NSString *)key delegate:(id )delegate userInfo:(NSDictionary *)info; 96 | 97 | /** 98 | * Remove the image from memory and disk cache synchronousely 99 | * 100 | * @param key The unique image cache key 101 | */ 102 | - (void)removeImageForKey:(NSString *)key; 103 | 104 | /** 105 | * Remove the image from memory and optionaly disk cache synchronousely 106 | * 107 | * @param key The unique image cache key 108 | * @param fromDisk Also remove cache entry from disk if YES 109 | */ 110 | - (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk; 111 | 112 | /** 113 | * Clear all memory cached images 114 | */ 115 | - (void)clearMemory; 116 | 117 | /** 118 | * Clear all disk cached images 119 | */ 120 | - (void)clearDisk; 121 | 122 | /** 123 | * Remove all expired cached image from disk 124 | */ 125 | - (void)cleanDisk; 126 | 127 | /** 128 | * Get the size used by the disk cache 129 | */ 130 | - (int)getSize; 131 | 132 | /** 133 | * Get the number of images in the disk cache 134 | */ 135 | - (int)getDiskCount; 136 | 137 | /** 138 | * Get the total size of images in memory cache 139 | */ 140 | - (int)getMemorySize; 141 | 142 | /** 143 | * Get the number of images in the memory cache 144 | */ 145 | - (int)getMemoryCount; 146 | 147 | @end 148 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/SDWebImageDecoder.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * Created by james on 9/28/11. 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | #import "SDWebImageDecoder.h" 12 | 13 | #define DECOMPRESSED_IMAGE_KEY @"decompressedImage" 14 | #define DECODE_INFO_KEY @"decodeInfo" 15 | 16 | #define IMAGE_KEY @"image" 17 | #define DELEGATE_KEY @"delegate" 18 | #define USER_INFO_KEY @"userInfo" 19 | 20 | @implementation SDWebImageDecoder 21 | static SDWebImageDecoder *sharedInstance; 22 | 23 | - (void)notifyDelegateOnMainThreadWithInfo:(NSDictionary *)dict 24 | { 25 | SDWIRetain(dict); 26 | NSDictionary *decodeInfo = [dict objectForKey:DECODE_INFO_KEY]; 27 | UIImage *decodedImage = [dict objectForKey:DECOMPRESSED_IMAGE_KEY]; 28 | 29 | id delegate = [decodeInfo objectForKey:DELEGATE_KEY]; 30 | NSDictionary *userInfo = [decodeInfo objectForKey:USER_INFO_KEY]; 31 | 32 | [delegate imageDecoder:self didFinishDecodingImage:decodedImage userInfo:userInfo]; 33 | SDWIRelease(dict); 34 | } 35 | 36 | - (void)decodeImageWithInfo:(NSDictionary *)decodeInfo 37 | { 38 | UIImage *image = [decodeInfo objectForKey:IMAGE_KEY]; 39 | 40 | UIImage *decompressedImage = [UIImage decodedImageWithImage:image]; 41 | if (!decompressedImage) 42 | { 43 | // If really have any error occurs, we use the original image at this moment 44 | decompressedImage = image; 45 | } 46 | 47 | NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: 48 | decompressedImage, DECOMPRESSED_IMAGE_KEY, 49 | decodeInfo, DECODE_INFO_KEY, nil]; 50 | 51 | [self performSelectorOnMainThread:@selector(notifyDelegateOnMainThreadWithInfo:) withObject:dict waitUntilDone:NO]; 52 | } 53 | 54 | - (id)init 55 | { 56 | if ((self = [super init])) 57 | { 58 | // Initialization code here. 59 | imageDecodingQueue = [[NSOperationQueue alloc] init]; 60 | } 61 | 62 | return self; 63 | } 64 | 65 | - (void)decodeImage:(UIImage *)image withDelegate:(id)delegate userInfo:(NSDictionary *)info 66 | { 67 | NSDictionary *decodeInfo = [NSDictionary dictionaryWithObjectsAndKeys: 68 | image, IMAGE_KEY, 69 | delegate, DELEGATE_KEY, 70 | info, USER_INFO_KEY, nil]; 71 | 72 | NSOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(decodeImageWithInfo:) object:decodeInfo]; 73 | [imageDecodingQueue addOperation:operation]; 74 | SDWIRelease(operation); 75 | } 76 | 77 | - (void)dealloc 78 | { 79 | SDWISafeRelease(imageDecodingQueue); 80 | SDWISuperDealoc; 81 | } 82 | 83 | + (SDWebImageDecoder *)sharedImageDecoder 84 | { 85 | if (!sharedInstance) 86 | { 87 | sharedInstance = [[SDWebImageDecoder alloc] init]; 88 | } 89 | return sharedInstance; 90 | } 91 | 92 | @end 93 | 94 | 95 | @implementation UIImage (ForceDecode) 96 | 97 | + (UIImage *)decodedImageWithImage:(UIImage *)image 98 | { 99 | CGImageRef imageRef = image.CGImage; 100 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 101 | CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef); 102 | 103 | BOOL imageHasAlphaInfo = (alphaInfo != kCGImageAlphaNone); 104 | 105 | int bytesPerPixel = imageHasAlphaInfo ? 4 : 3; 106 | CGBitmapInfo bitmapInfo = imageHasAlphaInfo ? kCGImageAlphaPremultipliedLast : kCGImageAlphaNone; 107 | 108 | CGContextRef context = CGBitmapContextCreate(NULL, 109 | CGImageGetWidth(imageRef), 110 | CGImageGetHeight(imageRef), 111 | 8, 112 | // Just always return width * bytesPerPixel will be enough 113 | CGImageGetWidth(imageRef) * bytesPerPixel, 114 | // System only supports RGB, set explicitly 115 | colorSpace, 116 | bitmapInfo); 117 | CGColorSpaceRelease(colorSpace); 118 | if (!context) return nil; 119 | 120 | CGRect rect = (CGRect){CGPointZero,{CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)}}; 121 | CGContextDrawImage(context, rect, imageRef); 122 | CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context); 123 | CGContextRelease(context); 124 | 125 | UIImage *decompressedImage = [[UIImage alloc] initWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation]; 126 | CGImageRelease(decompressedImageRef); 127 | return SDWIReturnAutoreleased(decompressedImage); 128 | } 129 | 130 | @end 131 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/UIImage+Resize/UIImage+Alpha.m: -------------------------------------------------------------------------------- 1 | // UIImage+Alpha.m 2 | // Created by Trevor Harmon on 9/20/09. 3 | // Free for personal or commercial use, with or without modification. 4 | // No warranty is expressed or implied. 5 | 6 | #import "UIImage+Alpha.h" 7 | 8 | // Private helper methods 9 | @interface UIImage () 10 | - (CGImageRef)newBorderMask:(NSUInteger)borderSize size:(CGSize)size; 11 | @end 12 | 13 | @implementation UIImage (Alpha) 14 | 15 | // Returns true if the image has an alpha layer 16 | - (BOOL)hasAlpha { 17 | CGImageAlphaInfo alpha = CGImageGetAlphaInfo(self.CGImage); 18 | return (alpha == kCGImageAlphaFirst || 19 | alpha == kCGImageAlphaLast || 20 | alpha == kCGImageAlphaPremultipliedFirst || 21 | alpha == kCGImageAlphaPremultipliedLast); 22 | } 23 | 24 | // Returns a copy of the given image, adding an alpha channel if it doesn't already have one 25 | - (UIImage *)imageWithAlpha { 26 | if ([self hasAlpha]) { 27 | return self; 28 | } 29 | 30 | CGImageRef imageRef = self.CGImage; 31 | size_t width = CGImageGetWidth(imageRef); 32 | size_t height = CGImageGetHeight(imageRef); 33 | 34 | // The bitsPerComponent and bitmapInfo values are hard-coded to prevent an "unsupported parameter combination" error 35 | CGContextRef offscreenContext = CGBitmapContextCreate(NULL, 36 | width, 37 | height, 38 | 8, 39 | 0, 40 | CGImageGetColorSpace(imageRef), 41 | kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst); 42 | 43 | // Draw the image into the context and retrieve the new image, which will now have an alpha layer 44 | CGContextDrawImage(offscreenContext, CGRectMake(0, 0, width, height), imageRef); 45 | CGImageRef imageRefWithAlpha = CGBitmapContextCreateImage(offscreenContext); 46 | UIImage *imageWithAlpha = [UIImage imageWithCGImage:imageRefWithAlpha]; 47 | 48 | // Clean up 49 | CGContextRelease(offscreenContext); 50 | CGImageRelease(imageRefWithAlpha); 51 | 52 | return imageWithAlpha; 53 | } 54 | 55 | // Returns a copy of the image with a transparent border of the given size added around its edges. 56 | // If the image has no alpha layer, one will be added to it. 57 | - (UIImage *)transparentBorderImage:(NSUInteger)borderSize { 58 | // If the image does not have an alpha layer, add one 59 | UIImage *image = [self imageWithAlpha]; 60 | 61 | CGRect newRect = CGRectMake(0, 0, image.size.width + borderSize * 2, image.size.height + borderSize * 2); 62 | 63 | // Build a context that's the same dimensions as the new size 64 | CGContextRef bitmap = CGBitmapContextCreate(NULL, 65 | newRect.size.width, 66 | newRect.size.height, 67 | CGImageGetBitsPerComponent(self.CGImage), 68 | 0, 69 | CGImageGetColorSpace(self.CGImage), 70 | CGImageGetBitmapInfo(self.CGImage)); 71 | 72 | // Draw the image in the center of the context, leaving a gap around the edges 73 | CGRect imageLocation = CGRectMake(borderSize, borderSize, image.size.width, image.size.height); 74 | CGContextDrawImage(bitmap, imageLocation, self.CGImage); 75 | CGImageRef borderImageRef = CGBitmapContextCreateImage(bitmap); 76 | 77 | // Create a mask to make the border transparent, and combine it with the image 78 | CGImageRef maskImageRef = [self newBorderMask:borderSize size:newRect.size]; 79 | CGImageRef transparentBorderImageRef = CGImageCreateWithMask(borderImageRef, maskImageRef); 80 | UIImage *transparentBorderImage = [UIImage imageWithCGImage:transparentBorderImageRef]; 81 | 82 | // Clean up 83 | CGContextRelease(bitmap); 84 | CGImageRelease(borderImageRef); 85 | CGImageRelease(maskImageRef); 86 | CGImageRelease(transparentBorderImageRef); 87 | 88 | return transparentBorderImage; 89 | } 90 | 91 | #pragma mark - 92 | #pragma mark Private helper methods 93 | 94 | // Creates a mask that makes the outer edges transparent and everything else opaque 95 | // The size must include the entire mask (opaque part + transparent border) 96 | // The caller is responsible for releasing the returned reference by calling CGImageRelease 97 | - (CGImageRef)newBorderMask:(NSUInteger)borderSize size:(CGSize)size { 98 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); 99 | 100 | // Build a context that's the same dimensions as the new size 101 | CGContextRef maskContext = CGBitmapContextCreate(NULL, 102 | size.width, 103 | size.height, 104 | 8, // 8-bit grayscale 105 | 0, 106 | colorSpace, 107 | kCGBitmapByteOrderDefault | kCGImageAlphaNone); 108 | 109 | // Start with a mask that's entirely transparent 110 | CGContextSetFillColorWithColor(maskContext, [UIColor blackColor].CGColor); 111 | CGContextFillRect(maskContext, CGRectMake(0, 0, size.width, size.height)); 112 | 113 | // Make the inner part (within the border) opaque 114 | CGContextSetFillColorWithColor(maskContext, [UIColor whiteColor].CGColor); 115 | CGContextFillRect(maskContext, CGRectMake(borderSize, borderSize, size.width - borderSize * 2, size.height - borderSize * 2)); 116 | 117 | // Get an image of the context 118 | CGImageRef maskImageRef = CGBitmapContextCreateImage(maskContext); 119 | 120 | // Clean up 121 | CGContextRelease(maskContext); 122 | CGColorSpaceRelease(colorSpace); 123 | 124 | return maskImageRef; 125 | } 126 | 127 | @end 128 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/UIImageView+WebCache.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "UIImageView+WebCache.h" 10 | 11 | @implementation UIImageView (WebCache) 12 | 13 | - (CGSize)doubleSizeIfRetina:(CGSize) size 14 | { 15 | BOOL isRetina = ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2); 16 | size = isRetina ? CGSizeMake(size.width *2, size.height *2) : size; 17 | return size; 18 | } 19 | 20 | - (void)setImageWithURL:(NSURL *)url andCropToBounds:(CGRect)bounds 21 | { 22 | [self setImageWithURL:url placeholderImage:nil options:0 andCropToBounds: bounds]; 23 | } 24 | 25 | - (void)setImageWithURL:(NSURL *)url andResize:(CGSize)size 26 | { 27 | size = [self doubleSizeIfRetina:size]; 28 | [self setImageWithURL:url placeholderImage:nil options:0 andResize:size]; 29 | } 30 | 31 | - (void)setImageWithURL:(NSURL *)url andResize:(CGSize)size withContentMode:(UIViewContentMode)mode 32 | { 33 | size = [self doubleSizeIfRetina:size]; 34 | [self setImageWithURL:url placeholderImage:nil options:0 andResize:size withContentMode:mode]; 35 | } 36 | 37 | - (void)setImageWithURL:(NSURL *)url 38 | { 39 | [self setImageWithURL:url placeholderImage:nil]; 40 | } 41 | 42 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder 43 | { 44 | [self setImageWithURL:url placeholderImage:placeholder options:0]; 45 | } 46 | 47 | -(void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder andCropToBounds:(CGRect)bounds{ 48 | [self setImageWithURL:url placeholderImage:nil options:0 andCropToBounds: bounds]; 49 | } 50 | 51 | 52 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options andCropToBounds:(CGRect)bounds; 53 | { 54 | SDWebImageManager *manager = [SDWebImageManager sharedManager]; 55 | 56 | // Remove in progress downloader from queue 57 | [manager cancelForDelegate:self]; 58 | 59 | self.image = placeholder; 60 | 61 | NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:@"crop", @"transformation", 62 | NSStringFromCGRect(bounds), @"bounds", nil]; 63 | 64 | if (url) 65 | { 66 | [manager downloadWithURL:url delegate:self options:options userInfo:userInfo]; 67 | } 68 | } 69 | 70 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options andResize:(CGSize)size 71 | { 72 | SDWebImageManager *manager = [SDWebImageManager sharedManager]; 73 | 74 | // Remove in progress downloader from queue 75 | [manager cancelForDelegate:self]; 76 | 77 | self.image = placeholder; 78 | 79 | NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:@"resize", @"transformation", 80 | NSStringFromCGSize(size), @"size", nil]; 81 | 82 | if (url) 83 | { 84 | [manager downloadWithURL:url delegate:self options:options userInfo:userInfo]; 85 | } 86 | } 87 | 88 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options andResize:(CGSize)size withContentMode:(UIViewContentMode)mode 89 | { 90 | SDWebImageManager *manager = [SDWebImageManager sharedManager]; 91 | 92 | // Remove in progress downloader from queue 93 | [manager cancelForDelegate:self]; 94 | 95 | self.image = placeholder; 96 | 97 | 98 | NSString *mode_str = nil; 99 | 100 | if (mode == UIViewContentModeScaleAspectFit) 101 | { 102 | mode_str = @"UIViewContentModeScaleAspectFit"; 103 | } 104 | else 105 | { 106 | if (mode == UIViewContentModeScaleAspectFill) 107 | { 108 | mode_str = @"UIViewContentModeScaleAspectFill"; 109 | } 110 | } 111 | 112 | NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:@"resize", @"transformation", 113 | NSStringFromCGSize(size), @"size", 114 | mode_str, @"content_mode", nil]; 115 | 116 | if (url) 117 | { 118 | [manager downloadWithURL:url delegate:self options:options userInfo:userInfo]; 119 | } 120 | } 121 | 122 | 123 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options 124 | { 125 | SDWebImageManager *manager = [SDWebImageManager sharedManager]; 126 | 127 | // Remove in progress downloader from queue 128 | [manager cancelForDelegate:self]; 129 | 130 | self.image = placeholder; 131 | 132 | if (url) 133 | { 134 | [manager downloadWithURL:url delegate:self options:options]; 135 | } 136 | } 137 | 138 | #if NS_BLOCKS_AVAILABLE 139 | - (void)setImageWithURL:(NSURL *)url success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 140 | { 141 | [self setImageWithURL:url placeholderImage:nil success:success failure:failure]; 142 | } 143 | 144 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 145 | { 146 | [self setImageWithURL:url placeholderImage:placeholder options:0 success:success failure:failure]; 147 | } 148 | 149 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 150 | { 151 | SDWebImageManager *manager = [SDWebImageManager sharedManager]; 152 | 153 | // Remove in progress downloader from queue 154 | [manager cancelForDelegate:self]; 155 | 156 | self.image = placeholder; 157 | 158 | if (url) 159 | { 160 | [manager downloadWithURL:url delegate:self options:options success:success failure:failure]; 161 | } 162 | } 163 | #endif 164 | 165 | - (void)cancelCurrentImageLoad 166 | { 167 | [[SDWebImageManager sharedManager] cancelForDelegate:self]; 168 | } 169 | 170 | - (void)webImageManager:(SDWebImageManager *)imageManager didProgressWithPartialImage:(UIImage *)image forURL:(NSURL *)url 171 | { 172 | self.image = image; 173 | [self setNeedsLayout]; 174 | } 175 | 176 | - (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image 177 | { 178 | self.image = image; 179 | [self setNeedsLayout]; 180 | } 181 | 182 | @end 183 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/UIButton+WebCache.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "UIButton+WebCache.h" 10 | #import "SDWebImageManager.h" 11 | 12 | @implementation UIButton (WebCache) 13 | 14 | - (void)setImageWithURL:(NSURL *)url 15 | { 16 | [self setImageWithURL:url placeholderImage:nil]; 17 | } 18 | 19 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder 20 | { 21 | [self setImageWithURL:url placeholderImage:placeholder options:0]; 22 | } 23 | 24 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options 25 | { 26 | SDWebImageManager *manager = [SDWebImageManager sharedManager]; 27 | 28 | // Remove in progress downloader from queue 29 | [manager cancelForDelegate:self]; 30 | 31 | [self setImage:placeholder forState:UIControlStateNormal]; 32 | [self setImage:placeholder forState:UIControlStateSelected]; 33 | [self setImage:placeholder forState:UIControlStateHighlighted]; 34 | 35 | 36 | if (url) 37 | { 38 | [manager downloadWithURL:url delegate:self options:options]; 39 | } 40 | } 41 | 42 | #if NS_BLOCKS_AVAILABLE 43 | - (void)setImageWithURL:(NSURL *)url success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 44 | { 45 | [self setImageWithURL:url placeholderImage:nil success:success failure:failure]; 46 | } 47 | 48 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 49 | { 50 | [self setImageWithURL:url placeholderImage:placeholder options:0 success:success failure:failure]; 51 | } 52 | 53 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 54 | { 55 | SDWebImageManager *manager = [SDWebImageManager sharedManager]; 56 | 57 | // Remove in progress downloader from queue 58 | [manager cancelForDelegate:self]; 59 | 60 | [self setImage:placeholder forState:UIControlStateNormal]; 61 | [self setImage:placeholder forState:UIControlStateSelected]; 62 | [self setImage:placeholder forState:UIControlStateHighlighted]; 63 | 64 | if (url) 65 | { 66 | [manager downloadWithURL:url delegate:self options:options success:success failure:failure]; 67 | } 68 | } 69 | #endif 70 | 71 | - (void)setBackgroundImageWithURL:(NSURL *)url 72 | { 73 | [self setBackgroundImageWithURL:url placeholderImage:nil]; 74 | } 75 | 76 | - (void)setBackgroundImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder 77 | { 78 | [self setBackgroundImageWithURL:url placeholderImage:placeholder options:0]; 79 | } 80 | 81 | - (void)setBackgroundImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options 82 | { 83 | SDWebImageManager *manager = [SDWebImageManager sharedManager]; 84 | 85 | // Remove in progress downloader from queue 86 | [manager cancelForDelegate:self]; 87 | 88 | [self setBackgroundImage:placeholder forState:UIControlStateNormal]; 89 | [self setBackgroundImage:placeholder forState:UIControlStateSelected]; 90 | [self setBackgroundImage:placeholder forState:UIControlStateHighlighted]; 91 | 92 | if (url) 93 | { 94 | NSDictionary *info = [NSDictionary dictionaryWithObject:@"background" forKey:@"type"]; 95 | [manager downloadWithURL:url delegate:self options:options userInfo:info]; 96 | } 97 | } 98 | 99 | #if NS_BLOCKS_AVAILABLE 100 | - (void)setBackgroundImageWithURL:(NSURL *)url success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 101 | { 102 | [self setBackgroundImageWithURL:url placeholderImage:nil success:success failure:failure]; 103 | } 104 | 105 | - (void)setBackgroundImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 106 | { 107 | [self setBackgroundImageWithURL:url placeholderImage:placeholder options:0 success:success failure:failure]; 108 | } 109 | 110 | - (void)setBackgroundImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 111 | { 112 | SDWebImageManager *manager = [SDWebImageManager sharedManager]; 113 | 114 | // Remove in progress downloader from queue 115 | [manager cancelForDelegate:self]; 116 | 117 | [self setBackgroundImage:placeholder forState:UIControlStateNormal]; 118 | [self setBackgroundImage:placeholder forState:UIControlStateSelected]; 119 | [self setBackgroundImage:placeholder forState:UIControlStateHighlighted]; 120 | 121 | if (url) 122 | { 123 | NSDictionary *info = [NSDictionary dictionaryWithObject:@"background" forKey:@"type"]; 124 | [manager downloadWithURL:url delegate:self options:options userInfo:info success:success failure:failure]; 125 | } 126 | } 127 | #endif 128 | 129 | 130 | - (void)cancelCurrentImageLoad 131 | { 132 | [[SDWebImageManager sharedManager] cancelForDelegate:self]; 133 | } 134 | 135 | - (void)webImageManager:(SDWebImageManager *)imageManager didProgressWithPartialImage:(UIImage *)image forURL:(NSURL *)url userInfo:(NSDictionary *)info 136 | { 137 | if ([[info valueForKey:@"type"] isEqualToString:@"background"]) 138 | { 139 | [self setBackgroundImage:image forState:UIControlStateNormal]; 140 | [self setBackgroundImage:image forState:UIControlStateSelected]; 141 | [self setBackgroundImage:image forState:UIControlStateHighlighted]; 142 | } 143 | else 144 | { 145 | [self setImage:image forState:UIControlStateNormal]; 146 | [self setImage:image forState:UIControlStateSelected]; 147 | [self setImage:image forState:UIControlStateHighlighted]; 148 | } 149 | } 150 | 151 | 152 | - (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image forURL:(NSURL *)url userInfo:(NSDictionary *)info 153 | { 154 | if ([[info valueForKey:@"type"] isEqualToString:@"background"]) 155 | { 156 | [self setBackgroundImage:image forState:UIControlStateNormal]; 157 | [self setBackgroundImage:image forState:UIControlStateSelected]; 158 | [self setBackgroundImage:image forState:UIControlStateHighlighted]; 159 | } 160 | else 161 | { 162 | [self setImage:image forState:UIControlStateNormal]; 163 | [self setImage:image forState:UIControlStateSelected]; 164 | [self setImage:image forState:UIControlStateHighlighted]; 165 | } 166 | } 167 | 168 | @end 169 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/SDWebImageManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageCompat.h" 10 | #import "SDWebImageDownloaderDelegate.h" 11 | #import "SDWebImageManagerDelegate.h" 12 | #import "SDImageCacheDelegate.h" 13 | 14 | typedef enum 15 | { 16 | SDWebImageRetryFailed = 1 << 0, 17 | SDWebImageLowPriority = 1 << 1, 18 | SDWebImageCacheMemoryOnly = 1 << 2, 19 | SDWebImageProgressiveDownload = 1 << 3 20 | } SDWebImageOptions; 21 | 22 | 23 | #if NS_BLOCKS_AVAILABLE 24 | typedef void(^SDWebImageSuccessBlock)(UIImage *image, BOOL cached); 25 | typedef void(^SDWebImageFailureBlock)(NSError *error); 26 | #endif 27 | 28 | /** 29 | * The SDWebImageManager is the class behind the UIImageView+WebCache category and likes. 30 | * It ties the asynchronous downloader (SDWebImageDownloader) with the image cache store (SDImageCache). 31 | * You can use this class directly to benefit from web image downloading with caching in another context than 32 | * a UIView. 33 | * 34 | * Here is a simple example of how to use SDWebImageManager: 35 | * 36 | * SDWebImageManager *manager = [SDWebImageManager sharedManager]; 37 | * [manager downloadWithURL:imageURL 38 | * delegate:self 39 | * options:0 40 | * success:^(UIImage *image, BOOL cached) 41 | * { 42 | * // do something with image 43 | * } 44 | * failure:nil]; 45 | */ 46 | @interface SDWebImageManager : NSObject 47 | { 48 | NSMutableArray *downloadInfo; 49 | NSMutableArray *downloadDelegates; 50 | NSMutableArray *downloaders; 51 | NSMutableArray *cacheDelegates; 52 | NSMutableArray *cacheURLs; 53 | NSMutableDictionary *downloaderForURL; 54 | NSMutableArray *failedURLs; 55 | } 56 | 57 | #if NS_BLOCKS_AVAILABLE 58 | typedef NSString *(^CacheKeyFilter)(NSURL *url); 59 | 60 | /** 61 | * The cache filter is a block used each time SDWebManager need to convert an URL into a cache key. This can 62 | * be used to remove dynamic part of an image URL. 63 | * 64 | * The following example sets a filter in the application delegate that will remove any query-string from the 65 | * URL before to use it as a cache key: 66 | * 67 | * [[SDWebImageManager sharedManager] setCacheKeyFilter:^(NSURL *url) 68 | * { 69 | * url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path]; 70 | * return [url absoluteString]; 71 | * }]; 72 | */ 73 | @property (strong) CacheKeyFilter cacheKeyFilter; 74 | #endif 75 | 76 | 77 | /** 78 | * Returns global SDWebImageManager instance. 79 | * 80 | * @return SDWebImageManager shared instance 81 | */ 82 | + (id)sharedManager; 83 | 84 | - (UIImage *)imageWithURL:(NSURL *)url __attribute__ ((deprecated)); 85 | 86 | /** 87 | * Downloads the image at the given URL if not present in cache or return the cached version otherwise. 88 | * 89 | * @param url The URL to the image 90 | * @param delegate The delegate object used to send result back 91 | * @see [SDWebImageManager downloadWithURL:delegate:options:userInfo:] 92 | * @see [SDWebImageManager downloadWithURL:delegate:options:userInfo:success:failure:] 93 | */ 94 | - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate; 95 | 96 | 97 | 98 | /** 99 | * Downloads the image at the given URL if not present in cache or return the cached version otherwise. 100 | * 101 | * @param url The URL to the image 102 | * @param delegate The delegate object used to send result back 103 | * @param options A mask to specify options to use for this request 104 | * @see [SDWebImageManager downloadWithURL:delegate:options:userInfo:] 105 | * @see [SDWebImageManager downloadWithURL:delegate:options:userInfo:success:failure:] 106 | */ 107 | - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate options:(SDWebImageOptions)options; 108 | 109 | 110 | 111 | /** 112 | * Downloads the image at the given URL if not present in cache or return the cached version otherwise. 113 | * 114 | * @param url The URL to the image 115 | * @param delegate The delegate object used to send result back 116 | * @param options A mask to specify options to use for this request 117 | * @param info An NSDictionnary passed back to delegate if provided 118 | * @see [SDWebImageManager downloadWithURL:delegate:options:success:failure:] 119 | */ 120 | - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate options:(SDWebImageOptions)options userInfo:(NSDictionary *)info; 121 | 122 | // use options:SDWebImageRetryFailed instead 123 | - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate retryFailed:(BOOL)retryFailed __attribute__ ((deprecated)); 124 | // use options:SDWebImageRetryFailed|SDWebImageLowPriority instead 125 | - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate retryFailed:(BOOL)retryFailed lowPriority:(BOOL)lowPriority __attribute__ ((deprecated)); 126 | 127 | #if NS_BLOCKS_AVAILABLE 128 | /** 129 | * Downloads the image at the given URL if not present in cache or return the cached version otherwise. 130 | * 131 | * @param url The URL to the image 132 | * @param delegate The delegate object used to send result back 133 | * @param options A mask to specify options to use for this request 134 | * @param success A block called when image has been retrived successfuly 135 | * @param failure A block called when couldn't be retrived for some reason 136 | * @see [SDWebImageManager downloadWithURL:delegate:options:] 137 | */ 138 | - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate options:(SDWebImageOptions)options success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 139 | 140 | /** 141 | * Downloads the image at the given URL if not present in cache or return the cached version otherwise. 142 | * 143 | * @param url The URL to the image 144 | * @param delegate The delegate object used to send result back 145 | * @param options A mask to specify options to use for this request 146 | * @param info An NSDictionnary passed back to delegate if provided 147 | * @param success A block called when image has been retrived successfuly 148 | * @param failure A block called when couldn't be retrived for some reason 149 | * @see [SDWebImageManager downloadWithURL:delegate:options:] 150 | */ 151 | - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate options:(SDWebImageOptions)options userInfo:(NSDictionary *)info success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 152 | #endif 153 | 154 | /** 155 | * Cancel all pending download requests for a given delegate 156 | * 157 | * @param delegate The delegate to cancel requests for 158 | */ 159 | - (void)cancelForDelegate:(id)delegate; 160 | 161 | @end 162 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/UIButton+WebCache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageCompat.h" 10 | #import "SDWebImageManagerDelegate.h" 11 | #import "SDWebImageManager.h" 12 | 13 | /** 14 | * Integrates SDWebImage async downloading and caching of remote images with UIButtonView. 15 | */ 16 | @interface UIButton (WebCache) 17 | 18 | /** 19 | * Set the imageView `image` with an `url`. 20 | * 21 | * The downloand is asynchronous and cached. 22 | * 23 | * @param url The url for the image. 24 | */ 25 | - (void)setImageWithURL:(NSURL *)url; 26 | 27 | /** 28 | * Set the imageView `image` with an `url` and a placeholder. 29 | * 30 | * The downloand is asynchronous and cached. 31 | * 32 | * @param url The url for the image. 33 | * @param placeholder The image to be set initially, until the image request finishes. 34 | * @see setImageWithURL:placeholderImage:options: 35 | */ 36 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; 37 | 38 | /** 39 | * Set the imageView `image` with an `url`, placeholder and custom options. 40 | * 41 | * The downloand is asynchronous and cached. 42 | * 43 | * @param url The url for the image. 44 | * @param placeholder The image to be set initially, until the image request finishes. 45 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 46 | */ 47 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; 48 | 49 | #if NS_BLOCKS_AVAILABLE 50 | /** 51 | * Set the imageView `image` with an `url`. 52 | * 53 | * The downloand is asynchronous and cached. 54 | * 55 | * @param url The url for the image. 56 | * @param success A block to be executed when the image request succeed This block has no return value and takes the retrieved image as argument. 57 | * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). 58 | */ 59 | - (void)setImageWithURL:(NSURL *)url success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 60 | 61 | /** 62 | * Set the imageView `image` with an `url`, placeholder. 63 | * 64 | * The downloand is asynchronous and cached. 65 | * 66 | * @param url The url for the image. 67 | * @param placeholder The image to be set initially, until the image request finishes. 68 | * @param success A block to be executed when the image request succeed This block has no return value and takes the retrieved image as argument. 69 | * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). 70 | */ 71 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 72 | 73 | /** 74 | * Set the imageView `image` with an `url`, placeholder and custom options. 75 | * 76 | * The downloand is asynchronous and cached. 77 | * 78 | * @param url The url for the image. 79 | * @param placeholder The image to be set initially, until the image request finishes. 80 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 81 | * @param success A block to be executed when the image request succeed This block has no return value and takes the retrieved image as argument. 82 | * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). 83 | */ 84 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 85 | #endif 86 | 87 | /** 88 | * Set the backgroundImageView `image` with an `url`. 89 | * 90 | * The downloand is asynchronous and cached. 91 | * 92 | * @param url The url for the image. 93 | */ 94 | - (void)setBackgroundImageWithURL:(NSURL *)url; 95 | 96 | /** 97 | * Set the backgroundImageView `image` with an `url` and a placeholder. 98 | * 99 | * The downloand is asynchronous and cached. 100 | * 101 | * @param url The url for the image. 102 | * @param placeholder The image to be set initially, until the image request finishes. 103 | * @see setImageWithURL:placeholderImage:options: 104 | */ 105 | - (void)setBackgroundImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; 106 | 107 | /** 108 | * Set the backgroundImageView `image` with an `url`, placeholder and custom options. 109 | * 110 | * The downloand is asynchronous and cached. 111 | * 112 | * @param url The url for the image. 113 | * @param placeholder The image to be set initially, until the image request finishes. 114 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 115 | */ 116 | - (void)setBackgroundImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; 117 | 118 | #if NS_BLOCKS_AVAILABLE 119 | /** 120 | * Set the backgroundImageView `image` with an `url`. 121 | * 122 | * The downloand is asynchronous and cached. 123 | * 124 | * @param url The url for the image. 125 | * @param success A block to be executed when the image request succeed This block has no return value and takes the retrieved image as argument. 126 | * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). 127 | */ 128 | - (void)setBackgroundImageWithURL:(NSURL *)url success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 129 | 130 | /** 131 | * Set the backgroundImageView `image` with an `url`, placeholder. 132 | * 133 | * The downloand is asynchronous and cached. 134 | * 135 | * @param url The url for the image. 136 | * @param placeholder The image to be set initially, until the image request finishes. 137 | * @param success A block to be executed when the image request succeed This block has no return value and takes the retrieved image as argument. 138 | * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). 139 | */ 140 | - (void)setBackgroundImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 141 | 142 | /** 143 | * Set the backgroundImageView `image` with an `url`, placeholder and custom options. 144 | * 145 | * The downloand is asynchronous and cached. 146 | * 147 | * @param url The url for the image. 148 | * @param placeholder The image to be set initially, until the image request finishes. 149 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 150 | * @param success A block to be executed when the image request succeed This block has no return value and takes the retrieved image as argument. 151 | * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). 152 | */ 153 | - (void)setBackgroundImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 154 | #endif 155 | 156 | 157 | /** 158 | * Cancel the current download 159 | */ 160 | - (void)cancelCurrentImageLoad; 161 | 162 | @end 163 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/UIImageView+WebCache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageCompat.h" 10 | #import "SDWebImageManagerDelegate.h" 11 | #import "SDWebImageManager.h" 12 | 13 | /** 14 | * Integrates SDWebImage async downloading and caching of remote images with UIImageView. 15 | * 16 | * Usage with a UITableViewCell sub-class: 17 | * 18 | * #import 19 | * 20 | * ... 21 | * 22 | * - (UITableViewCell *)tableView:(UITableView *)tableView 23 | * cellForRowAtIndexPath:(NSIndexPath *)indexPath 24 | * { 25 | * static NSString *MyIdentifier = @"MyIdentifier"; 26 | * 27 | * UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; 28 | * 29 | * if (cell == nil) 30 | * { 31 | * cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 32 | * reuseIdentifier:MyIdentifier] autorelease]; 33 | * } 34 | * 35 | * // Here we use the provided setImageWithURL: method to load the web image 36 | * // Ensure you use a placeholder image otherwise cells will be initialized with no image 37 | * [cell.imageView setImageWithURL:[NSURL URLWithString:@"http://example.com/image.jpg"] 38 | * placeholderImage:[UIImage imageNamed:@"placeholder"]]; 39 | * 40 | * cell.textLabel.text = @"My Text"; 41 | * return cell; 42 | * } 43 | * 44 | */ 45 | @interface UIImageView (WebCache) 46 | 47 | 48 | /** 49 | * Set the imageView `image` with an `url`. 50 | * 51 | * The downloand is asynchronous and cached. After the image is downloaded the result image is cropped. 52 | * 53 | * @param url The url for the image. 54 | * @param bounds Bounds of the cropped image. 55 | */ 56 | - (void)setImageWithURL:(NSURL *)url andCropToBounds:(CGRect)bounds; 57 | 58 | 59 | /** 60 | * Set the imageView `image` with an `url`. 61 | * 62 | * The downloand is asynchronous and cached. After the image is downloaded the result image is cropped. 63 | * 64 | * @param url The url for the image. 65 | * @param size Resize the downloaded image to the specified size 66 | */ 67 | - (void)setImageWithURL:(NSURL *)url andResize:(CGSize)size; 68 | 69 | /** 70 | * Set the imageView `image` with an `url`. 71 | * 72 | * The downloand is asynchronous and cached. After the image is downloaded the result image is cropped. 73 | * 74 | * @param url The url for the image. 75 | * @param bounds Bounds of the cropped image. 76 | * @param size Resize the downloaded image to the specified size 77 | * @param mode Content mode of the resize strategy. Can be UIViewContentModeScaleAspectFill or UIViewContentModeScaleAspectFit 78 | */ 79 | - (void)setImageWithURL:(NSURL *)url andResize:(CGSize)size withContentMode:(UIViewContentMode)mode; 80 | 81 | 82 | /** 83 | * Set the imageView `image` with an `url`. 84 | * 85 | * The downloand is asynchronous and cached. 86 | * 87 | * @param url The url for the image. 88 | */ 89 | - (void)setImageWithURL:(NSURL *)url; 90 | 91 | 92 | 93 | /** 94 | * Set the imageView `image` with an `url` and a placeholder. 95 | * 96 | * The downloand is asynchronous and cached. After the image is downloaded the result image is cropped. 97 | * 98 | * @param url The url for the image. 99 | * @param placeholder The image to be set initially, until the image request finishes. 100 | * @param bounds Bounds of the cropped image. 101 | * @see setImageWithURL:placeholderImage:options:andCropToBounds: 102 | */ 103 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder andCropToBounds:(CGRect)bounds; 104 | 105 | 106 | 107 | /** 108 | * Set the imageView `image` with an `url` and a placeholder. 109 | * 110 | * The downloand is asynchronous and cached. After the image is downloaded the result image is cropped. 111 | * 112 | * @param url The url for the image. 113 | * @param placeholder The image to be set initially, until the image request finishes. 114 | * @param size Resize the downloaded image to the specified size 115 | * @see setImageWithURL:placeholderImage:options:andResize: 116 | */ 117 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options andResize:(CGSize)size; 118 | 119 | /** 120 | * Set the imageView `image` with an `url` and a placeholder. 121 | * 122 | * The downloand is asynchronous and cached. After the image is downloaded the result image is cropped. 123 | * 124 | * @param url The url for the image. 125 | * @param placeholder The image to be set initially, until the image request finishes. 126 | * @param size Resize the downloaded image to the specified size 127 | * @param mode Content mode of the resize strategy. Can be UIViewContentModeScaleAspectFill or UIViewContentModeScaleAspectFit 128 | * @see setImageWithURL:placeholderImage:options:andResize:withContentMode: 129 | */ 130 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options andResize:(CGSize)size withContentMode:(UIViewContentMode)mode; 131 | 132 | 133 | 134 | /** 135 | * Set the imageView `image` with an `url` and a placeholder. 136 | * 137 | * The downloand is asynchronous and cached. 138 | * 139 | * @param url The url for the image. 140 | * @param placeholder The image to be set initially, until the image request finishes. 141 | * @see setImageWithURL:placeholderImage:options: 142 | */ 143 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; 144 | 145 | 146 | /** 147 | * Set the imageView `image` with an `url`, placeholder and custom options. 148 | * 149 | * The downloand is asynchronous and cached. After the image is downloaded the result image is cropped. 150 | * 151 | * @param url The url for the image. 152 | * @param placeholder The image to be set initially, until the image request finishes. 153 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 154 | * @param bounds Bounds of the cropped image. 155 | */ 156 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options andCropToBounds:(CGRect)bounds; 157 | 158 | 159 | /** 160 | * Set the imageView `image` with an `url`, placeholder and custom options. 161 | * 162 | * The downloand is asynchronous and cached. 163 | * 164 | * @param url The url for the image. 165 | * @param placeholder The image to be set initially, until the image request finishes. 166 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 167 | */ 168 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; 169 | 170 | #if NS_BLOCKS_AVAILABLE 171 | /** 172 | * Set the imageView `image` with an `url`. 173 | * 174 | * The downloand is asynchronous and cached. 175 | * 176 | * @param url The url for the image. 177 | * @param success A block to be executed when the image request succeed This block has no return value and takes the retrieved image as argument. 178 | * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). 179 | */ 180 | - (void)setImageWithURL:(NSURL *)url success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 181 | 182 | /** 183 | * Set the imageView `image` with an `url`, placeholder. 184 | * 185 | * The downloand is asynchronous and cached. 186 | * 187 | * @param url The url for the image. 188 | * @param placeholder The image to be set initially, until the image request finishes. 189 | * @param success A block to be executed when the image request succeed This block has no return value and takes the retrieved image as argument. 190 | * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). 191 | */ 192 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 193 | 194 | /** 195 | * Set the imageView `image` with an `url`, placeholder and custom options. 196 | * 197 | * The downloand is asynchronous and cached. 198 | * 199 | * @param url The url for the image. 200 | * @param placeholder The image to be set initially, until the image request finishes. 201 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 202 | * @param success A block to be executed when the image request succeed This block has no return value and takes the retrieved image as argument. 203 | * @param failure A block object to be executed when the image request failed. This block has no return value and takes the error object describing the network or parsing error that occurred (may be nil). 204 | */ 205 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure; 206 | #endif 207 | 208 | /** 209 | * Cancel the current download 210 | */ 211 | - (void)cancelCurrentImageLoad; 212 | 213 | @end 214 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/UIImage+Resize/UIImage+Resize.m: -------------------------------------------------------------------------------- 1 | // UIImage+Resize.m 2 | // Created by Trevor Harmon on 8/5/09. 3 | // Free for personal or commercial use, with or without modification. 4 | // No warranty is expressed or implied. 5 | 6 | #import "UIImage+Resize.h" 7 | 8 | // Private helper methods 9 | @interface UIImage () 10 | - (UIImage *)resizedImage:(CGImageRef)imageRef 11 | size:(CGSize)newSize 12 | transform:(CGAffineTransform)transform 13 | drawTransposed:(BOOL)transpose 14 | interpolationQuality:(CGInterpolationQuality)quality; 15 | - (CGAffineTransform)transformForOrientation:(CGSize)newSize; 16 | 17 | @end 18 | 19 | @implementation UIImage (Resize) 20 | 21 | // Returns a copy of this image that is cropped to the given bounds. 22 | // The bounds will be adjusted using CGRectIntegral. 23 | // This method does not ignore the image's imageOrientation setting. 24 | - (UIImage *)croppedImage:(CGRect)bounds { 25 | CGAffineTransform txTranslate; 26 | CGAffineTransform txCompound; 27 | CGRect adjustedBounds; 28 | BOOL drawTransposed; 29 | 30 | switch (self.imageOrientation) { 31 | case UIImageOrientationDown: 32 | case UIImageOrientationDownMirrored: 33 | txTranslate = CGAffineTransformMakeTranslation(self.size.width, self.size.height); 34 | txCompound = CGAffineTransformRotate(txTranslate, M_PI); 35 | adjustedBounds = CGRectApplyAffineTransform(bounds, txCompound); 36 | drawTransposed = NO; 37 | break; 38 | case UIImageOrientationLeft: 39 | case UIImageOrientationLeftMirrored: 40 | txTranslate = CGAffineTransformMakeTranslation(self.size.height, 0.0); 41 | txCompound = CGAffineTransformRotate(txTranslate, M_PI_2); 42 | adjustedBounds = CGRectApplyAffineTransform(bounds, txCompound); 43 | drawTransposed = YES; 44 | break; 45 | case UIImageOrientationRight: 46 | case UIImageOrientationRightMirrored: 47 | txTranslate = CGAffineTransformMakeTranslation(0.0, self.size.width); 48 | txCompound = CGAffineTransformRotate(txTranslate, M_PI + M_PI_2); 49 | adjustedBounds = CGRectApplyAffineTransform(bounds, txCompound); 50 | drawTransposed = YES; 51 | break; 52 | default: 53 | adjustedBounds = bounds; 54 | drawTransposed = NO; 55 | } 56 | 57 | CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], adjustedBounds); 58 | UIImage *croppedImage; 59 | if (CGRectEqualToRect(adjustedBounds, bounds)) 60 | croppedImage = [UIImage imageWithCGImage:imageRef]; 61 | else 62 | croppedImage = [self resizedImage:imageRef 63 | size:bounds.size 64 | transform:[self transformForOrientation:bounds.size] 65 | drawTransposed:drawTransposed 66 | interpolationQuality:kCGInterpolationHigh]; 67 | CGImageRelease(imageRef); 68 | return croppedImage; 69 | } 70 | 71 | // Returns a copy of this image that is squared to the thumbnail size. 72 | // If transparentBorder is non-zero, a transparent border of the given size will be added around the edges of the thumbnail. (Adding a transparent border of at least one pixel in size has the side-effect of antialiasing the edges of the image when rotating it using Core Animation.) 73 | - (UIImage *)thumbnailImage:(NSInteger)thumbnailSize 74 | interpolationQuality:(CGInterpolationQuality)quality { 75 | UIImage *resizedImage = [self resizedImageWithContentMode:UIViewContentModeScaleAspectFill 76 | bounds:CGSizeMake(thumbnailSize, thumbnailSize) 77 | interpolationQuality:quality]; 78 | 79 | // Crop out any part of the image that's larger than the thumbnail size 80 | // The cropped rect must be centered on the resized image 81 | // Round the origin points so that the size isn't altered when CGRectIntegral is later invoked 82 | CGRect cropRect = CGRectMake(round((resizedImage.size.width - thumbnailSize) / 2), 83 | round((resizedImage.size.height - thumbnailSize) / 2), 84 | thumbnailSize, 85 | thumbnailSize); 86 | UIImage *croppedImage = [resizedImage croppedImage:cropRect]; 87 | 88 | return croppedImage; 89 | } 90 | 91 | // Returns a rescaled copy of the image, taking into account its orientation 92 | // The image will be scaled disproportionately if necessary to fit the bounds specified by the parameter 93 | - (UIImage *)resizedImage:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)quality { 94 | BOOL drawTransposed; 95 | 96 | switch (self.imageOrientation) { 97 | case UIImageOrientationLeft: 98 | case UIImageOrientationLeftMirrored: 99 | case UIImageOrientationRight: 100 | case UIImageOrientationRightMirrored: 101 | drawTransposed = YES; 102 | break; 103 | 104 | default: 105 | drawTransposed = NO; 106 | } 107 | return [self resizedImage:self.CGImage 108 | size:newSize 109 | transform:[self transformForOrientation:newSize] 110 | drawTransposed:drawTransposed 111 | interpolationQuality:quality]; 112 | } 113 | 114 | // Resizes the image according to the given content mode, taking into account the image's orientation 115 | - (UIImage *)resizedImageWithContentMode:(UIViewContentMode)contentMode 116 | bounds:(CGSize)bounds 117 | interpolationQuality:(CGInterpolationQuality)quality { 118 | CGFloat horizontalRatio = bounds.width / self.size.width; 119 | CGFloat verticalRatio = bounds.height / self.size.height; 120 | CGFloat ratio; 121 | 122 | switch (contentMode) { 123 | case UIViewContentModeScaleAspectFill: 124 | ratio = MAX(horizontalRatio, verticalRatio); 125 | break; 126 | 127 | case UIViewContentModeScaleAspectFit: 128 | ratio = MIN(horizontalRatio, verticalRatio); 129 | break; 130 | 131 | default: 132 | [NSException raise:NSInvalidArgumentException format:@"Unsupported content mode: %d", contentMode]; 133 | } 134 | 135 | CGSize newSize = CGSizeMake(self.size.width * ratio, self.size.height * ratio); 136 | 137 | return [self resizedImage:newSize interpolationQuality:quality]; 138 | } 139 | 140 | #pragma mark - 141 | #pragma mark Private helper methods 142 | 143 | // Returns a copy of the image that has been transformed using the given affine transform and scaled to the new size 144 | // The new image's orientation will be UIImageOrientationUp, regardless of the current image's orientation 145 | // If the new size is not integral, it will be rounded up 146 | - (UIImage *)resizedImage:(CGImageRef)imageRef 147 | size:(CGSize)newSize 148 | transform:(CGAffineTransform)transform 149 | drawTransposed:(BOOL)transpose 150 | interpolationQuality:(CGInterpolationQuality)quality { 151 | CGRect newRect; 152 | if ([self respondsToSelector:@selector(scale)]) 153 | newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width * self.scale, newSize.height * self.scale)); 154 | else 155 | newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height)); 156 | CGRect transposedRect = CGRectMake(0, 0, newRect.size.height, newRect.size.width); 157 | //CGImageRef imageRef = self.CGImage; 158 | 159 | // Build a context that's the same dimensions as the new size 160 | CGContextRef bitmap = CGBitmapContextCreate(NULL, 161 | newRect.size.width, 162 | newRect.size.height, 163 | CGImageGetBitsPerComponent(imageRef), 164 | 0, 165 | CGImageGetColorSpace(imageRef), 166 | CGImageGetBitmapInfo(imageRef)); 167 | 168 | // Rotate and/or flip the image if required by its orientation 169 | CGContextConcatCTM(bitmap, transform); 170 | 171 | // Set the quality level to use when rescaling 172 | CGContextSetInterpolationQuality(bitmap, quality); 173 | 174 | // Draw into the context; this scales the image 175 | CGContextDrawImage(bitmap, transpose ? transposedRect : newRect, imageRef); 176 | 177 | // Get the resized image from the context and a UIImage 178 | CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap); 179 | UIImage *newImage; 180 | if ([self respondsToSelector:@selector(scale)] && [UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) { 181 | newImage = [UIImage imageWithCGImage:newImageRef scale:self.scale orientation:self.imageOrientation]; 182 | } else { 183 | newImage = [UIImage imageWithCGImage:newImageRef]; 184 | } 185 | 186 | 187 | // Clean up 188 | CGContextRelease(bitmap); 189 | CGImageRelease(newImageRef); 190 | 191 | return newImage; 192 | } 193 | 194 | // Returns an affine transform that takes into account the image orientation when drawing a scaled image 195 | - (CGAffineTransform)transformForOrientation:(CGSize)newSize { 196 | CGAffineTransform transform = CGAffineTransformIdentity; 197 | 198 | switch (self.imageOrientation) { 199 | case UIImageOrientationDown: // EXIF = 3 200 | case UIImageOrientationDownMirrored: // EXIF = 4 201 | transform = CGAffineTransformTranslate(transform, newSize.width, newSize.height); 202 | transform = CGAffineTransformRotate(transform, M_PI); 203 | break; 204 | 205 | case UIImageOrientationLeft: // EXIF = 6 206 | case UIImageOrientationLeftMirrored: // EXIF = 5 207 | transform = CGAffineTransformTranslate(transform, newSize.width, 0); 208 | transform = CGAffineTransformRotate(transform, M_PI_2); 209 | break; 210 | 211 | case UIImageOrientationRight: // EXIF = 8 212 | case UIImageOrientationRightMirrored: // EXIF = 7 213 | transform = CGAffineTransformTranslate(transform, 0, newSize.height); 214 | transform = CGAffineTransformRotate(transform, -M_PI_2); 215 | break; 216 | 217 | case UIImageOrientationUp: 218 | case UIImageOrientationUpMirrored: 219 | break; 220 | } 221 | 222 | switch (self.imageOrientation) { 223 | case UIImageOrientationUpMirrored: // EXIF = 2 224 | case UIImageOrientationDownMirrored: // EXIF = 4 225 | transform = CGAffineTransformTranslate(transform, newSize.width, 0); 226 | transform = CGAffineTransformScale(transform, -1, 1); 227 | break; 228 | 229 | case UIImageOrientationLeftMirrored: // EXIF = 5 230 | case UIImageOrientationRightMirrored: // EXIF = 7 231 | transform = CGAffineTransformTranslate(transform, newSize.height, 0); 232 | transform = CGAffineTransformScale(transform, -1, 1); 233 | break; 234 | 235 | default: 236 | break; 237 | } 238 | 239 | return transform; 240 | } 241 | 242 | @end -------------------------------------------------------------------------------- /Image Cache Resize/en.lproj/MainStoryboard_iPhone.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 | 48 | 57 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 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 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/SDWebImageDownloader.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageDownloader.h" 10 | #import "SDWebImageDecoder.h" 11 | #import 12 | 13 | @interface SDWebImageDownloader (ImageDecoder) 14 | @end 15 | 16 | NSString *const SDWebImageDownloadStartNotification = @"SDWebImageDownloadStartNotification"; 17 | NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNotification"; 18 | 19 | @interface SDWebImageDownloader () 20 | @property (nonatomic, retain) NSURLConnection *connection; 21 | @end 22 | 23 | @implementation SDWebImageDownloader 24 | @synthesize url, delegate, connection, imageData, userInfo, lowPriority, progressive; 25 | 26 | #pragma mark Public Methods 27 | 28 | + (id)downloaderWithURL:(NSURL *)url delegate:(id)delegate 29 | { 30 | return [self downloaderWithURL:url delegate:delegate userInfo:nil]; 31 | } 32 | 33 | + (id)downloaderWithURL:(NSURL *)url delegate:(id)delegate userInfo:(id)userInfo 34 | { 35 | return [self downloaderWithURL:url delegate:delegate userInfo:userInfo lowPriority:NO]; 36 | } 37 | 38 | + (id)downloaderWithURL:(NSURL *)url delegate:(id)delegate userInfo:(id)userInfo lowPriority:(BOOL)lowPriority 39 | { 40 | // Bind SDNetworkActivityIndicator if available (download it here: http://github.com/rs/SDNetworkActivityIndicator ) 41 | // To use it, just add #import "SDNetworkActivityIndicator.h" in addition to the SDWebImage import 42 | if (NSClassFromString(@"SDNetworkActivityIndicator")) 43 | { 44 | 45 | #pragma clang diagnostic push 46 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 47 | id activityIndicator = [NSClassFromString(@"SDNetworkActivityIndicator") performSelector:NSSelectorFromString(@"sharedActivityIndicator")]; 48 | #pragma clang diagnostic pop 49 | 50 | // Remove observer in case it was previously added. 51 | [[NSNotificationCenter defaultCenter] removeObserver:activityIndicator name:SDWebImageDownloadStartNotification object:nil]; 52 | [[NSNotificationCenter defaultCenter] removeObserver:activityIndicator name:SDWebImageDownloadStopNotification object:nil]; 53 | 54 | [[NSNotificationCenter defaultCenter] addObserver:activityIndicator 55 | selector:NSSelectorFromString(@"startActivity") 56 | name:SDWebImageDownloadStartNotification object:nil]; 57 | [[NSNotificationCenter defaultCenter] addObserver:activityIndicator 58 | selector:NSSelectorFromString(@"stopActivity") 59 | name:SDWebImageDownloadStopNotification object:nil]; 60 | } 61 | 62 | SDWebImageDownloader *downloader = SDWIReturnAutoreleased([[SDWebImageDownloader alloc] init]); 63 | downloader.url = url; 64 | downloader.delegate = delegate; 65 | downloader.userInfo = userInfo; 66 | downloader.lowPriority = lowPriority; 67 | [downloader performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:YES]; 68 | return downloader; 69 | } 70 | 71 | + (void)setMaxConcurrentDownloads:(NSUInteger)max 72 | { 73 | // NOOP 74 | } 75 | 76 | - (void)start 77 | { 78 | // In order to prevent from potential duplicate caching (NSURLCache + SDImageCache) we disable the cache for image requests 79 | NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15]; 80 | self.connection = SDWIReturnAutoreleased([[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]); 81 | 82 | // If not in low priority mode, ensure we aren't blocked by UI manipulations (default runloop mode for NSURLConnection is NSEventTrackingRunLoopMode) 83 | if (!lowPriority) 84 | { 85 | [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; 86 | } 87 | [connection start]; 88 | SDWIRelease(request); 89 | 90 | if (connection) 91 | { 92 | [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:nil]; 93 | } 94 | else 95 | { 96 | if ([delegate respondsToSelector:@selector(imageDownloader:didFailWithError:)]) 97 | { 98 | [delegate performSelector:@selector(imageDownloader:didFailWithError:) withObject:self withObject:nil]; 99 | } 100 | } 101 | } 102 | 103 | - (void)cancel 104 | { 105 | if (connection) 106 | { 107 | [connection cancel]; 108 | self.connection = nil; 109 | [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil]; 110 | } 111 | } 112 | 113 | #pragma mark NSURLConnection (delegate) 114 | 115 | - (void)connection:(NSURLConnection *)aConnection didReceiveResponse:(NSURLResponse *)response 116 | { 117 | if (![response respondsToSelector:@selector(statusCode)] || [((NSHTTPURLResponse *)response) statusCode] < 400) 118 | { 119 | expectedSize = response.expectedContentLength > 0 ? (NSUInteger)response.expectedContentLength : 0; 120 | self.imageData = SDWIReturnAutoreleased([[NSMutableData alloc] initWithCapacity:expectedSize]); 121 | } 122 | else 123 | { 124 | [aConnection cancel]; 125 | 126 | [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil]; 127 | 128 | if ([delegate respondsToSelector:@selector(imageDownloader:didFailWithError:)]) 129 | { 130 | NSError *error = [[NSError alloc] initWithDomain:NSURLErrorDomain 131 | code:[((NSHTTPURLResponse *)response) statusCode] 132 | userInfo:nil]; 133 | [delegate performSelector:@selector(imageDownloader:didFailWithError:) withObject:self withObject:error]; 134 | SDWIRelease(error); 135 | } 136 | 137 | self.connection = nil; 138 | self.imageData = nil; 139 | } 140 | } 141 | 142 | - (void)connection:(NSURLConnection *)aConnection didReceiveData:(NSData *)data 143 | { 144 | [imageData appendData:data]; 145 | 146 | if (CGImageSourceCreateImageAtIndex == NULL) 147 | { 148 | // ImageIO isn't present in iOS < 4 149 | self.progressive = NO; 150 | } 151 | 152 | if (self.progressive && expectedSize > 0 && [delegate respondsToSelector:@selector(imageDownloader:didUpdatePartialImage:)]) 153 | { 154 | // The following code is from http://www.cocoaintheshell.com/2011/05/progressive-images-download-imageio/ 155 | // Thanks to the author @Nyx0uf 156 | 157 | // Get the total bytes downloaded 158 | const NSUInteger totalSize = [imageData length]; 159 | 160 | // Update the data source, we must pass ALL the data, not just the new bytes 161 | CGImageSourceRef imageSource = CGImageSourceCreateIncremental(NULL); 162 | #if __has_feature(objc_arc) 163 | CGImageSourceUpdateData(imageSource, (__bridge CFDataRef)imageData, totalSize == expectedSize); 164 | #else 165 | CGImageSourceUpdateData(imageSource, (CFDataRef)imageData, totalSize == expectedSize); 166 | #endif 167 | 168 | if (width + height == 0) 169 | { 170 | CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL); 171 | if (properties) 172 | { 173 | CFTypeRef val = CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight); 174 | if (val) CFNumberGetValue(val, kCFNumberLongType, &height); 175 | val = CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth); 176 | if (val) CFNumberGetValue(val, kCFNumberLongType, &width); 177 | CFRelease(properties); 178 | } 179 | } 180 | 181 | if (width + height > 0 && totalSize < expectedSize) 182 | { 183 | // Create the image 184 | CGImageRef partialImageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL); 185 | 186 | #ifdef TARGET_OS_IPHONE 187 | // Workaround for iOS anamorphic image 188 | if (partialImageRef) 189 | { 190 | const size_t partialHeight = CGImageGetHeight(partialImageRef); 191 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 192 | CGContextRef bmContext = CGBitmapContextCreate(NULL, width, height, 8, width * 4, colorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst); 193 | CGColorSpaceRelease(colorSpace); 194 | if (bmContext) 195 | { 196 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = partialHeight}, partialImageRef); 197 | CGImageRelease(partialImageRef); 198 | partialImageRef = CGBitmapContextCreateImage(bmContext); 199 | CGContextRelease(bmContext); 200 | } 201 | else 202 | { 203 | CGImageRelease(partialImageRef); 204 | partialImageRef = nil; 205 | } 206 | } 207 | #endif 208 | 209 | if (partialImageRef) 210 | { 211 | UIImage *image = SDScaledImageForPath(url.absoluteString, [UIImage imageWithCGImage:partialImageRef]); 212 | [[SDWebImageDecoder sharedImageDecoder] decodeImage:image 213 | withDelegate:self 214 | userInfo:[NSDictionary dictionaryWithObject:@"partial" forKey:@"type"]]; 215 | 216 | CGImageRelease(partialImageRef); 217 | } 218 | } 219 | 220 | CFRelease(imageSource); 221 | } 222 | } 223 | 224 | #pragma GCC diagnostic ignored "-Wundeclared-selector" 225 | - (void)connectionDidFinishLoading:(NSURLConnection *)aConnection 226 | { 227 | self.connection = nil; 228 | 229 | [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil]; 230 | 231 | if ([delegate respondsToSelector:@selector(imageDownloaderDidFinish:)]) 232 | { 233 | [delegate performSelector:@selector(imageDownloaderDidFinish:) withObject:self]; 234 | } 235 | 236 | if ([delegate respondsToSelector:@selector(imageDownloader:didFinishWithImage:)]) 237 | { 238 | UIImage *image = SDScaledImageForPath(url.absoluteString, imageData); 239 | [[SDWebImageDecoder sharedImageDecoder] decodeImage:image withDelegate:self userInfo:nil]; 240 | } 241 | } 242 | 243 | - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 244 | { 245 | [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil]; 246 | 247 | if ([delegate respondsToSelector:@selector(imageDownloader:didFailWithError:)]) 248 | { 249 | [delegate performSelector:@selector(imageDownloader:didFailWithError:) withObject:self withObject:error]; 250 | } 251 | 252 | self.connection = nil; 253 | self.imageData = nil; 254 | } 255 | 256 | #pragma mark SDWebImageDecoderDelegate 257 | 258 | - (void)imageDecoder:(SDWebImageDecoder *)decoder didFinishDecodingImage:(UIImage *)image userInfo:(NSDictionary *)aUserInfo 259 | { 260 | if ([[aUserInfo valueForKey:@"type"] isEqualToString:@"partial"]) 261 | { 262 | [delegate imageDownloader:self didUpdatePartialImage:image]; 263 | } 264 | else 265 | { 266 | [delegate performSelector:@selector(imageDownloader:didFinishWithImage:) withObject:self withObject:image]; 267 | } 268 | } 269 | 270 | #pragma mark NSObject 271 | 272 | - (void)dealloc 273 | { 274 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 275 | SDWISafeRelease(url); 276 | SDWISafeRelease(connection); 277 | SDWISafeRelease(imageData); 278 | SDWISafeRelease(userInfo); 279 | SDWISuperDealoc; 280 | } 281 | 282 | 283 | @end 284 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/SDImageCache.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDImageCache.h" 10 | #import "SDWebImageDecoder.h" 11 | #import 12 | #import "SDWebImageDecoder.h" 13 | #import 14 | #import 15 | 16 | static SDImageCache *instance; 17 | 18 | static NSInteger cacheMaxCacheAge = 60*60*24*7; // 1 week 19 | static natural_t minFreeMemLeft = 1024*1024*12; // reserve 12MB RAM 20 | 21 | // inspired by http://stackoverflow.com/questions/5012886/knowing-available-ram-on-an-ios-device 22 | static natural_t get_free_memory(void) 23 | { 24 | mach_port_t host_port; 25 | mach_msg_type_number_t host_size; 26 | vm_size_t pagesize; 27 | 28 | host_port = mach_host_self(); 29 | host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t); 30 | host_page_size(host_port, &pagesize); 31 | 32 | vm_statistics_data_t vm_stat; 33 | 34 | if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) 35 | { 36 | NSLog(@"Failed to fetch vm statistics"); 37 | return 0; 38 | } 39 | 40 | /* Stats in bytes */ 41 | natural_t mem_free = vm_stat.free_count * pagesize; 42 | return mem_free; 43 | } 44 | 45 | @implementation SDImageCache 46 | 47 | #pragma mark NSObject 48 | 49 | - (id)init 50 | { 51 | if ((self = [super init])) 52 | { 53 | // Init the memory cache 54 | memCache = [[NSMutableDictionary alloc] init]; 55 | 56 | // Init the disk cache 57 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 58 | diskCachePath = SDWIReturnRetained([[paths objectAtIndex:0] stringByAppendingPathComponent:@"ImageCache"]); 59 | 60 | if (![[NSFileManager defaultManager] fileExistsAtPath:diskCachePath]) 61 | { 62 | [[NSFileManager defaultManager] createDirectoryAtPath:diskCachePath 63 | withIntermediateDirectories:YES 64 | attributes:nil 65 | error:NULL]; 66 | } 67 | 68 | // Init the operation queue 69 | cacheInQueue = [[NSOperationQueue alloc] init]; 70 | cacheInQueue.maxConcurrentOperationCount = 1; 71 | cacheOutQueue = [[NSOperationQueue alloc] init]; 72 | cacheOutQueue.maxConcurrentOperationCount = 1; 73 | 74 | #if TARGET_OS_IPHONE 75 | // Subscribe to app events 76 | [[NSNotificationCenter defaultCenter] addObserver:self 77 | selector:@selector(clearMemory) 78 | name:UIApplicationDidReceiveMemoryWarningNotification 79 | object:nil]; 80 | 81 | [[NSNotificationCenter defaultCenter] addObserver:self 82 | selector:@selector(cleanDisk) 83 | name:UIApplicationWillTerminateNotification 84 | object:nil]; 85 | 86 | #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_4_0 87 | UIDevice *device = [UIDevice currentDevice]; 88 | if ([device respondsToSelector:@selector(isMultitaskingSupported)] && device.multitaskingSupported) 89 | { 90 | // When in background, clean memory in order to have less chance to be killed 91 | [[NSNotificationCenter defaultCenter] addObserver:self 92 | selector:@selector(clearMemory) 93 | name:UIApplicationDidEnterBackgroundNotification 94 | object:nil]; 95 | } 96 | #endif 97 | #endif 98 | } 99 | 100 | return self; 101 | } 102 | 103 | - (void)dealloc 104 | { 105 | SDWISafeRelease(memCache); 106 | SDWISafeRelease(diskCachePath); 107 | SDWISafeRelease(cacheInQueue); 108 | 109 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 110 | 111 | SDWISuperDealoc; 112 | } 113 | 114 | #pragma mark SDImageCache (class methods) 115 | 116 | + (SDImageCache *)sharedImageCache 117 | { 118 | if (instance == nil) 119 | { 120 | instance = [[SDImageCache alloc] init]; 121 | } 122 | 123 | return instance; 124 | } 125 | 126 | + (void) setMaxCacheAge:(NSInteger)maxCacheAge 127 | { 128 | cacheMaxCacheAge = maxCacheAge; 129 | } 130 | 131 | #pragma mark SDImageCache (private) 132 | 133 | - (NSString *)cachePathForKey:(NSString *)key 134 | { 135 | const char *str = [key UTF8String]; 136 | unsigned char r[CC_MD5_DIGEST_LENGTH]; 137 | CC_MD5(str, (CC_LONG)strlen(str), r); 138 | NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 139 | r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]]; 140 | 141 | return [diskCachePath stringByAppendingPathComponent:filename]; 142 | } 143 | 144 | - (void)storeKeyWithDataToDisk:(NSArray *)keyAndData 145 | { 146 | // Can't use defaultManager another thread 147 | NSFileManager *fileManager = [[NSFileManager alloc] init]; 148 | 149 | NSString *key = [keyAndData objectAtIndex:0]; 150 | NSData *data = [keyAndData count] > 1 ? [keyAndData objectAtIndex:1] : nil; 151 | 152 | if (data) 153 | { 154 | [fileManager createFileAtPath:[self cachePathForKey:key] contents:data attributes:nil]; 155 | } 156 | else 157 | { 158 | // If no data representation given, convert the UIImage in JPEG and store it 159 | // This trick is more CPU/memory intensive and doesn't preserve alpha channel 160 | UIImage *image = SDWIReturnRetained([self imageFromKey:key fromDisk:YES]); // be thread safe with no lock 161 | if (image) 162 | { 163 | #if TARGET_OS_IPHONE 164 | [fileManager createFileAtPath:[self cachePathForKey:key] contents:UIImageJPEGRepresentation(image, (CGFloat)1.0) attributes:nil]; 165 | #else 166 | NSArray* representations = [image representations]; 167 | NSData* jpegData = [NSBitmapImageRep representationOfImageRepsInArray: representations usingType: NSJPEGFileType properties:nil]; 168 | [fileManager createFileAtPath:[self cachePathForKey:key] contents:jpegData attributes:nil]; 169 | #endif 170 | SDWIRelease(image); 171 | } 172 | } 173 | 174 | SDWIRelease(fileManager); 175 | } 176 | 177 | - (void)notifyDelegate:(NSDictionary *)arguments 178 | { 179 | NSString *key = [arguments objectForKey:@"key"]; 180 | id delegate = [arguments objectForKey:@"delegate"]; 181 | NSDictionary *info = [arguments objectForKey:@"userInfo"]; 182 | UIImage *image = [arguments objectForKey:@"image"]; 183 | 184 | if (image) 185 | { 186 | if (get_free_memory() < minFreeMemLeft) 187 | { 188 | [memCache removeAllObjects]; 189 | } 190 | [memCache setObject:image forKey:key]; 191 | 192 | if ([delegate respondsToSelector:@selector(imageCache:didFindImage:forKey:userInfo:)]) 193 | { 194 | [delegate imageCache:self didFindImage:image forKey:key userInfo:info]; 195 | } 196 | } 197 | else 198 | { 199 | if ([delegate respondsToSelector:@selector(imageCache:didNotFindImageForKey:userInfo:)]) 200 | { 201 | [delegate imageCache:self didNotFindImageForKey:key userInfo:info]; 202 | } 203 | } 204 | } 205 | 206 | - (void)queryDiskCacheOperation:(NSDictionary *)arguments 207 | { 208 | NSString *key = [arguments objectForKey:@"key"]; 209 | NSMutableDictionary *mutableArguments = SDWIReturnAutoreleased([arguments mutableCopy]); 210 | 211 | UIImage *image = SDScaledImageForPath(key, [NSData dataWithContentsOfFile:[self cachePathForKey:key]]); 212 | 213 | if (image) 214 | { 215 | UIImage *decodedImage = [UIImage decodedImageWithImage:image]; 216 | if (decodedImage) 217 | { 218 | image = decodedImage; 219 | } 220 | 221 | [mutableArguments setObject:image forKey:@"image"]; 222 | } 223 | 224 | [self performSelectorOnMainThread:@selector(notifyDelegate:) withObject:mutableArguments waitUntilDone:NO]; 225 | } 226 | 227 | #pragma mark ImageCache 228 | 229 | - (void)storeImage:(UIImage *)image imageData:(NSData *)data forKey:(NSString *)key toDisk:(BOOL)toDisk 230 | { 231 | if (!image || !key) 232 | { 233 | return; 234 | } 235 | 236 | if (get_free_memory() < minFreeMemLeft) 237 | { 238 | [memCache removeAllObjects]; 239 | } 240 | [memCache setObject:image forKey:key]; 241 | 242 | if (toDisk) 243 | { 244 | NSArray *keyWithData; 245 | if (data) 246 | { 247 | keyWithData = [NSArray arrayWithObjects:key, data, nil]; 248 | } 249 | else 250 | { 251 | keyWithData = [NSArray arrayWithObjects:key, nil]; 252 | } 253 | 254 | NSInvocationOperation *operation = SDWIReturnAutoreleased([[NSInvocationOperation alloc] initWithTarget:self 255 | selector:@selector(storeKeyWithDataToDisk:) 256 | object:keyWithData]); 257 | [cacheInQueue addOperation:operation]; 258 | } 259 | } 260 | 261 | - (void)storeImage:(UIImage *)image forKey:(NSString *)key 262 | { 263 | [self storeImage:image imageData:nil forKey:key toDisk:YES]; 264 | } 265 | 266 | - (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk 267 | { 268 | [self storeImage:image imageData:nil forKey:key toDisk:toDisk]; 269 | } 270 | 271 | 272 | - (UIImage *)imageFromKey:(NSString *)key 273 | { 274 | return [self imageFromKey:key fromDisk:YES]; 275 | } 276 | 277 | - (UIImage *)imageFromKey:(NSString *)key fromDisk:(BOOL)fromDisk 278 | { 279 | if (key == nil) 280 | { 281 | return nil; 282 | } 283 | 284 | UIImage *image = [memCache objectForKey:key]; 285 | 286 | if (!image && fromDisk) 287 | { 288 | image = SDScaledImageForPath(key, [NSData dataWithContentsOfFile:[self cachePathForKey:key]]); 289 | if (image) 290 | { 291 | if (get_free_memory() < minFreeMemLeft) 292 | { 293 | [memCache removeAllObjects]; 294 | } 295 | [memCache setObject:image forKey:key]; 296 | } 297 | } 298 | 299 | return image; 300 | } 301 | 302 | - (void)queryDiskCacheForKey:(NSString *)key delegate:(id )delegate userInfo:(NSDictionary *)info 303 | { 304 | if (!delegate) 305 | { 306 | return; 307 | } 308 | 309 | if (!key) 310 | { 311 | if ([delegate respondsToSelector:@selector(imageCache:didNotFindImageForKey:userInfo:)]) 312 | { 313 | [delegate imageCache:self didNotFindImageForKey:key userInfo:info]; 314 | } 315 | return; 316 | } 317 | 318 | // First check the in-memory cache... 319 | UIImage *image = [memCache objectForKey:key]; 320 | if (image) 321 | { 322 | // ...notify delegate immediately, no need to go async 323 | if ([delegate respondsToSelector:@selector(imageCache:didFindImage:forKey:userInfo:)]) 324 | { 325 | [delegate imageCache:self didFindImage:image forKey:key userInfo:info]; 326 | } 327 | return; 328 | } 329 | 330 | NSMutableDictionary *arguments = [NSMutableDictionary dictionaryWithCapacity:3]; 331 | [arguments setObject:key forKey:@"key"]; 332 | [arguments setObject:delegate forKey:@"delegate"]; 333 | if (info) 334 | { 335 | [arguments setObject:info forKey:@"userInfo"]; 336 | } 337 | NSInvocationOperation *operation = SDWIReturnAutoreleased([[NSInvocationOperation alloc] initWithTarget:self 338 | selector:@selector(queryDiskCacheOperation:) 339 | object:arguments]); 340 | [cacheOutQueue addOperation:operation]; 341 | } 342 | 343 | - (void)removeImageForKey:(NSString *)key 344 | { 345 | [self removeImageForKey:key fromDisk:YES]; 346 | } 347 | 348 | - (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk 349 | { 350 | if (key == nil) 351 | { 352 | return; 353 | } 354 | 355 | [memCache removeObjectForKey:key]; 356 | 357 | if (fromDisk) 358 | { 359 | [[NSFileManager defaultManager] removeItemAtPath:[self cachePathForKey:key] error:nil]; 360 | } 361 | } 362 | 363 | - (void)clearMemory 364 | { 365 | [cacheInQueue cancelAllOperations]; // won't be able to complete 366 | [memCache removeAllObjects]; 367 | } 368 | 369 | - (void)clearDisk 370 | { 371 | [cacheInQueue cancelAllOperations]; 372 | [[NSFileManager defaultManager] removeItemAtPath:diskCachePath error:nil]; 373 | [[NSFileManager defaultManager] createDirectoryAtPath:diskCachePath 374 | withIntermediateDirectories:YES 375 | attributes:nil 376 | error:NULL]; 377 | } 378 | 379 | - (void)cleanDisk 380 | { 381 | NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:-cacheMaxCacheAge]; 382 | NSDirectoryEnumerator *fileEnumerator = [[NSFileManager defaultManager] enumeratorAtPath:diskCachePath]; 383 | for (NSString *fileName in fileEnumerator) 384 | { 385 | NSString *filePath = [diskCachePath stringByAppendingPathComponent:fileName]; 386 | NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil]; 387 | if ([[[attrs fileModificationDate] laterDate:expirationDate] isEqualToDate:expirationDate]) 388 | { 389 | [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil]; 390 | } 391 | } 392 | } 393 | 394 | -(int)getSize 395 | { 396 | int size = 0; 397 | NSDirectoryEnumerator *fileEnumerator = [[NSFileManager defaultManager] enumeratorAtPath:diskCachePath]; 398 | for (NSString *fileName in fileEnumerator) 399 | { 400 | NSString *filePath = [diskCachePath stringByAppendingPathComponent:fileName]; 401 | NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil]; 402 | size += [attrs fileSize]; 403 | } 404 | return size; 405 | } 406 | 407 | - (int)getDiskCount 408 | { 409 | int count = 0; 410 | NSDirectoryEnumerator *fileEnumerator = [[NSFileManager defaultManager] enumeratorAtPath:diskCachePath]; 411 | for (NSString *fileName in fileEnumerator) 412 | { 413 | count += 1; 414 | } 415 | 416 | return count; 417 | } 418 | 419 | - (int)getMemorySize 420 | { 421 | int size = 0; 422 | 423 | for(id key in [memCache allKeys]) 424 | { 425 | UIImage *img = [memCache valueForKey:key]; 426 | size += [UIImageJPEGRepresentation(img, 0) length]; 427 | }; 428 | 429 | return size; 430 | } 431 | 432 | - (int)getMemoryCount 433 | { 434 | return [[memCache allKeys] count]; 435 | } 436 | 437 | @end 438 | -------------------------------------------------------------------------------- /Image Cache Resize/Libraries/SDWebImage/SDWebImageManager.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * For the full copyright and license information, please view the LICENSE 6 | * file that was distributed with this source code. 7 | */ 8 | 9 | #import "SDWebImageManager.h" 10 | #import "SDImageCache.h" 11 | #import "SDWebImageDownloader.h" 12 | #import 13 | 14 | #import "UIImage+Resize.h" 15 | 16 | static SDWebImageManager *instance; 17 | 18 | @implementation SDWebImageManager 19 | 20 | #if NS_BLOCKS_AVAILABLE 21 | @synthesize cacheKeyFilter; 22 | #endif 23 | 24 | - (id)init 25 | { 26 | if ((self = [super init])) 27 | { 28 | downloadInfo = [[NSMutableArray alloc] init]; 29 | downloadDelegates = [[NSMutableArray alloc] init]; 30 | downloaders = [[NSMutableArray alloc] init]; 31 | cacheDelegates = [[NSMutableArray alloc] init]; 32 | cacheURLs = [[NSMutableArray alloc] init]; 33 | downloaderForURL = [[NSMutableDictionary alloc] init]; 34 | failedURLs = [[NSMutableArray alloc] init]; 35 | } 36 | return self; 37 | } 38 | 39 | - (void)dealloc 40 | { 41 | SDWISafeRelease(downloadInfo); 42 | SDWISafeRelease(downloadDelegates); 43 | SDWISafeRelease(downloaders); 44 | SDWISafeRelease(cacheDelegates); 45 | SDWISafeRelease(cacheURLs); 46 | SDWISafeRelease(downloaderForURL); 47 | SDWISafeRelease(failedURLs); 48 | SDWISuperDealoc; 49 | } 50 | 51 | 52 | + (id)sharedManager 53 | { 54 | if (instance == nil) 55 | { 56 | instance = [[SDWebImageManager alloc] init]; 57 | } 58 | 59 | return instance; 60 | } 61 | 62 | - (NSString *)cacheKeyForURL:(NSURL *)url andDictionary:(NSDictionary *) info 63 | { 64 | NSString *transformation = [info objectForKey:@"transformation"]; 65 | 66 | NSString *cacheKey = [self cacheKeyForURL:url]; 67 | if (transformation) 68 | { 69 | if ([transformation isEqualToString:@"crop"]) 70 | { 71 | cacheKey = [NSString stringWithFormat:@"%@_crop_%@", [self cacheKeyForURL:url], [info objectForKey:@"bounds"]]; 72 | } 73 | else 74 | { 75 | if ([transformation isEqualToString:@"resize"]) 76 | { 77 | NSString *contentmode = [info objectForKey:@"content_mode"]; 78 | if (contentmode) 79 | { 80 | cacheKey = [NSString stringWithFormat:@"%@_resize_%@_%@", [self cacheKeyForURL:url], [info objectForKey:@"size"], contentmode]; 81 | } 82 | else 83 | { 84 | cacheKey = [NSString stringWithFormat:@"%@_resize_%@", [self cacheKeyForURL:url], [info objectForKey:@"size"]]; 85 | } 86 | 87 | } 88 | } 89 | } 90 | return cacheKey; 91 | } 92 | 93 | 94 | - (NSString *)cacheKeyForURL:(NSURL *)url 95 | { 96 | #if NS_BLOCKS_AVAILABLE 97 | if (self.cacheKeyFilter) 98 | { 99 | return self.cacheKeyFilter(url); 100 | } 101 | else 102 | { 103 | return [url absoluteString]; 104 | } 105 | #else 106 | return [url absoluteString]; 107 | #endif 108 | } 109 | 110 | /* 111 | * @deprecated 112 | */ 113 | - (UIImage *)imageWithURL:(NSURL *)url 114 | { 115 | return [[SDImageCache sharedImageCache] imageFromKey:[self cacheKeyForURL:url]]; 116 | } 117 | 118 | /* 119 | * @deprecated 120 | */ 121 | - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate retryFailed:(BOOL)retryFailed 122 | { 123 | [self downloadWithURL:url delegate:delegate options:(retryFailed ? SDWebImageRetryFailed : 0)]; 124 | } 125 | 126 | /* 127 | * @deprecated 128 | */ 129 | - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate retryFailed:(BOOL)retryFailed lowPriority:(BOOL)lowPriority 130 | { 131 | SDWebImageOptions options = 0; 132 | if (retryFailed) options |= SDWebImageRetryFailed; 133 | if (lowPriority) options |= SDWebImageLowPriority; 134 | [self downloadWithURL:url delegate:delegate options:options]; 135 | } 136 | 137 | - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate 138 | { 139 | [self downloadWithURL:url delegate:delegate options:0]; 140 | } 141 | 142 | - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate options:(SDWebImageOptions)options 143 | { 144 | [self downloadWithURL:url delegate:delegate options:options userInfo:nil]; 145 | } 146 | 147 | 148 | - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate options:(SDWebImageOptions)options userInfo:(NSDictionary *)userInfo 149 | { 150 | // Very common mistake is to send the URL using NSString object instead of NSURL. For some strange reason, XCode won't 151 | // throw any warning for this type mismatch. Here we failsafe this error by allowing URLs to be passed as NSString. 152 | if ([url isKindOfClass:NSString.class]) 153 | { 154 | url = [NSURL URLWithString:(NSString *)url]; 155 | } 156 | else if (![url isKindOfClass:NSURL.class]) 157 | { 158 | url = nil; // Prevent some common crashes due to common wrong values passed like NSNull.null for instance 159 | } 160 | 161 | if (!url || !delegate || (!(options & SDWebImageRetryFailed) && [failedURLs containsObject:url])) 162 | { 163 | return; 164 | } 165 | 166 | // Check the on-disk cache async so we don't block the main thread 167 | [cacheDelegates addObject:delegate]; 168 | [cacheURLs addObject:url]; 169 | NSMutableDictionary *info = [NSMutableDictionary dictionaryWithObjectsAndKeys: 170 | delegate, @"delegate", 171 | url, @"url", 172 | [NSNumber numberWithInt:options], @"options", 173 | userInfo ? userInfo : [NSNull null], @"userInfo", 174 | nil]; 175 | 176 | NSArray *transformationKeys = [NSArray arrayWithObjects:@"transformation", @"bounds", @"size", @"content_mode", nil]; 177 | 178 | for (NSString *key in transformationKeys) { 179 | NSString *value = [userInfo objectForKey:key]; 180 | if (value) 181 | { 182 | [info setObject:value forKey:key]; 183 | } 184 | } 185 | 186 | NSString *cacheKey = [self cacheKeyForURL:url andDictionary:info]; 187 | 188 | [[SDImageCache sharedImageCache] queryDiskCacheForKey:cacheKey delegate:self userInfo:info]; 189 | } 190 | 191 | #if NS_BLOCKS_AVAILABLE 192 | - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate options:(SDWebImageOptions)options success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure 193 | { 194 | [self downloadWithURL:url delegate:delegate options:options userInfo:nil success:success failure:failure]; 195 | } 196 | 197 | - (void)downloadWithURL:(NSURL *)url delegate:(id)delegate options:(SDWebImageOptions)options userInfo:(NSDictionary *)userInfo success:(SDWebImageSuccessBlock)success failure:(SDWebImageFailureBlock)failure 198 | { 199 | // repeated logic from above due to requirement for backwards compatability for iOS versions without blocks 200 | 201 | // Very common mistake is to send the URL using NSString object instead of NSURL. For some strange reason, XCode won't 202 | // throw any warning for this type mismatch. Here we failsafe this error by allowing URLs to be passed as NSString. 203 | if ([url isKindOfClass:NSString.class]) 204 | { 205 | url = [NSURL URLWithString:(NSString *)url]; 206 | } 207 | 208 | if (!url || !delegate || (!(options & SDWebImageRetryFailed) && [failedURLs containsObject:url])) 209 | { 210 | return; 211 | } 212 | 213 | // Check the on-disk cache async so we don't block the main thread 214 | [cacheDelegates addObject:delegate]; 215 | [cacheURLs addObject:url]; 216 | SDWebImageSuccessBlock successCopy = [success copy]; 217 | SDWebImageFailureBlock failureCopy = [failure copy]; 218 | NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys: 219 | delegate, @"delegate", 220 | url, @"url", 221 | [NSNumber numberWithInt:options], @"options", 222 | userInfo ? userInfo : [NSNull null], @"userInfo", 223 | successCopy, @"success", 224 | failureCopy, @"failure", 225 | nil]; 226 | SDWIRelease(successCopy); 227 | SDWIRelease(failureCopy); 228 | [[SDImageCache sharedImageCache] queryDiskCacheForKey:[self cacheKeyForURL:url] delegate:self userInfo:info]; 229 | } 230 | #endif 231 | 232 | - (void)cancelForDelegate:(id)delegate 233 | { 234 | NSUInteger idx; 235 | while ((idx = [cacheDelegates indexOfObjectIdenticalTo:delegate]) != NSNotFound) 236 | { 237 | [cacheDelegates removeObjectAtIndex:idx]; 238 | [cacheURLs removeObjectAtIndex:idx]; 239 | } 240 | 241 | while ((idx = [downloadDelegates indexOfObjectIdenticalTo:delegate]) != NSNotFound) 242 | { 243 | SDWebImageDownloader *downloader = SDWIReturnRetained([downloaders objectAtIndex:idx]); 244 | 245 | [downloadInfo removeObjectAtIndex:idx]; 246 | [downloadDelegates removeObjectAtIndex:idx]; 247 | [downloaders removeObjectAtIndex:idx]; 248 | 249 | if (![downloaders containsObject:downloader]) 250 | { 251 | // No more delegate are waiting for this download, cancel it 252 | [downloader cancel]; 253 | NSString *downloaderkey = [self cacheKeyForURL:downloader.url andDictionary:downloader.userInfo]; 254 | [downloaderForURL removeObjectForKey:downloaderkey]; 255 | } 256 | 257 | SDWIRelease(downloader); 258 | } 259 | } 260 | 261 | #pragma mark SDImageCacheDelegate 262 | 263 | - (NSUInteger)indexOfDelegate:(id)delegate waitingForURL:(NSURL *)url 264 | { 265 | // Do a linear search, simple (even if inefficient) 266 | NSUInteger idx; 267 | for (idx = 0; idx < [cacheDelegates count]; idx++) 268 | { 269 | if ([cacheDelegates objectAtIndex:idx] == delegate && [[cacheURLs objectAtIndex:idx] isEqual:url]) 270 | { 271 | return idx; 272 | } 273 | } 274 | return NSNotFound; 275 | } 276 | 277 | - (void)imageCache:(SDImageCache *)imageCache didFindImage:(UIImage *)image forKey:(NSString *)key userInfo:(NSDictionary *)info 278 | { 279 | NSURL *url = [info objectForKey:@"url"]; 280 | id delegate = [info objectForKey:@"delegate"]; 281 | 282 | NSUInteger idx = [self indexOfDelegate:delegate waitingForURL:url]; 283 | if (idx == NSNotFound) 284 | { 285 | // Request has since been canceled 286 | return; 287 | } 288 | 289 | if ([delegate respondsToSelector:@selector(webImageManager:didFinishWithImage:)]) 290 | { 291 | [delegate performSelector:@selector(webImageManager:didFinishWithImage:) withObject:self withObject:image]; 292 | } 293 | if ([delegate respondsToSelector:@selector(webImageManager:didFinishWithImage:forURL:)]) 294 | { 295 | objc_msgSend(delegate, @selector(webImageManager:didFinishWithImage:forURL:), self, image, url); 296 | } 297 | if ([delegate respondsToSelector:@selector(webImageManager:didFinishWithImage:forURL:userInfo:)]) 298 | { 299 | NSDictionary *userInfo = [info objectForKey:@"userInfo"]; 300 | if ([userInfo isKindOfClass:NSNull.class]) 301 | { 302 | userInfo = nil; 303 | } 304 | objc_msgSend(delegate, @selector(webImageManager:didFinishWithImage:forURL:userInfo:), self, image, url, userInfo); 305 | } 306 | #if NS_BLOCKS_AVAILABLE 307 | if ([info objectForKey:@"success"]) 308 | { 309 | SDWebImageSuccessBlock success = [info objectForKey:@"success"]; 310 | success(image, YES); 311 | } 312 | #endif 313 | 314 | [cacheDelegates removeObjectAtIndex:idx]; 315 | [cacheURLs removeObjectAtIndex:idx]; 316 | } 317 | 318 | - (void)imageCache:(SDImageCache *)imageCache didNotFindImageForKey:(NSString *)key userInfo:(NSDictionary *)info 319 | { 320 | NSURL *url = [info objectForKey:@"url"]; 321 | id delegate = [info objectForKey:@"delegate"]; 322 | SDWebImageOptions options = [[info objectForKey:@"options"] intValue]; 323 | 324 | NSUInteger idx = [self indexOfDelegate:delegate waitingForURL:url]; 325 | if (idx == NSNotFound) 326 | { 327 | // Request has since been canceled 328 | return; 329 | } 330 | 331 | [cacheDelegates removeObjectAtIndex:idx]; 332 | [cacheURLs removeObjectAtIndex:idx]; 333 | 334 | NSString *downloaderkey = [self cacheKeyForURL:url andDictionary:info]; 335 | // Share the same downloader for identical URLs so we don't download the same URL several times 336 | SDWebImageDownloader *downloader = [downloaderForURL objectForKey:downloaderkey]; 337 | 338 | if (!downloader) 339 | { 340 | downloader = [SDWebImageDownloader downloaderWithURL:url delegate:self userInfo:info lowPriority:(options & SDWebImageLowPriority)]; 341 | [downloaderForURL setObject:downloader forKey:downloaderkey]; 342 | } 343 | else 344 | { 345 | // Reuse shared downloader 346 | downloader.lowPriority = (options & SDWebImageLowPriority); 347 | } 348 | 349 | if ((options & SDWebImageProgressiveDownload) && !downloader.progressive) 350 | { 351 | // Turn progressive download support on demand 352 | downloader.progressive = YES; 353 | } 354 | 355 | [downloadInfo addObject:info]; 356 | [downloadDelegates addObject:delegate]; 357 | [downloaders addObject:downloader]; 358 | } 359 | 360 | #pragma mark SDWebImageDownloaderDelegate 361 | 362 | - (void)imageDownloader:(SDWebImageDownloader *)downloader didUpdatePartialImage:(UIImage *)image 363 | { 364 | // Notify all the downloadDelegates with this downloader 365 | for (NSInteger idx = (NSInteger)[downloaders count] - 1; idx >= 0; idx--) 366 | { 367 | NSUInteger uidx = (NSUInteger)idx; 368 | SDWebImageDownloader *aDownloader = [downloaders objectAtIndex:uidx]; 369 | if (aDownloader == downloader) 370 | { 371 | id delegate = [downloadDelegates objectAtIndex:uidx]; 372 | SDWIRetain(delegate); 373 | SDWIAutorelease(delegate); 374 | 375 | if ([delegate respondsToSelector:@selector(webImageManager:didProgressWithPartialImage:forURL:)]) 376 | { 377 | objc_msgSend(delegate, @selector(webImageManager:didProgressWithPartialImage:forURL:), self, image, downloader.url); 378 | } 379 | if ([delegate respondsToSelector:@selector(webImageManager:didProgressWithPartialImage:forURL:userInfo:)]) 380 | { 381 | NSDictionary *userInfo = [[downloadInfo objectAtIndex:uidx] objectForKey:@"userInfo"]; 382 | if ([userInfo isKindOfClass:NSNull.class]) 383 | { 384 | userInfo = nil; 385 | } 386 | objc_msgSend(delegate, @selector(webImageManager:didProgressWithPartialImage:forURL:userInfo:), self, image, downloader.url, userInfo); 387 | } 388 | } 389 | } 390 | } 391 | 392 | - (void)imageDownloader:(SDWebImageDownloader *)downloader didFinishWithImage:(UIImage *)image 393 | { 394 | SDWIRetain(downloader); 395 | 396 | 397 | if ([downloader.userInfo objectForKey:@"transformation"] == @"crop") 398 | { 399 | CGRect bounds = CGRectFromString([downloader.userInfo objectForKey:@"bounds"]); 400 | image = [image croppedImage:bounds]; 401 | downloader.imageData = [UIImagePNGRepresentation(image) copy]; 402 | } 403 | else 404 | { 405 | if ([downloader.userInfo objectForKey:@"transformation"] == @"resize") 406 | { 407 | CGSize size = CGSizeFromString([downloader.userInfo objectForKey:@"size"]); 408 | NSString *contentmode = [downloader.userInfo objectForKey:@"content_mode"]; 409 | if (contentmode) 410 | { 411 | UIViewContentMode mode = UIViewContentModeScaleAspectFit; 412 | 413 | if ([contentmode isEqualToString:@"UIViewContentModeScaleAspectFill"]) 414 | { 415 | mode = UIViewContentModeScaleAspectFill; 416 | } 417 | 418 | image = [image resizedImageWithContentMode:mode bounds:size interpolationQuality:kCGInterpolationHigh]; 419 | } 420 | else 421 | { 422 | image = [image resizedImage:size interpolationQuality:kCGInterpolationHigh]; 423 | } 424 | downloader.imageData = [UIImagePNGRepresentation(image) copy]; 425 | 426 | } 427 | } 428 | 429 | SDWebImageOptions options = [[downloader.userInfo objectForKey:@"options"] intValue]; 430 | 431 | // Notify all the downloadDelegates with this downloader 432 | for (NSInteger idx = (NSInteger)[downloaders count] - 1; idx >= 0; idx--) 433 | { 434 | NSUInteger uidx = (NSUInteger)idx; 435 | SDWebImageDownloader *aDownloader = [downloaders objectAtIndex:uidx]; 436 | if (aDownloader == downloader) 437 | { 438 | id delegate = [downloadDelegates objectAtIndex:uidx]; 439 | SDWIRetain(delegate); 440 | SDWIAutorelease(delegate); 441 | 442 | if (image) 443 | { 444 | if ([delegate respondsToSelector:@selector(webImageManager:didFinishWithImage:)]) 445 | { 446 | [delegate performSelector:@selector(webImageManager:didFinishWithImage:) withObject:self withObject:image]; 447 | } 448 | if ([delegate respondsToSelector:@selector(webImageManager:didFinishWithImage:forURL:)]) 449 | { 450 | objc_msgSend(delegate, @selector(webImageManager:didFinishWithImage:forURL:), self, image, downloader.url); 451 | } 452 | if ([delegate respondsToSelector:@selector(webImageManager:didFinishWithImage:forURL:userInfo:)]) 453 | { 454 | NSDictionary *userInfo = [[downloadInfo objectAtIndex:uidx] objectForKey:@"userInfo"]; 455 | if ([userInfo isKindOfClass:NSNull.class]) 456 | { 457 | userInfo = nil; 458 | } 459 | objc_msgSend(delegate, @selector(webImageManager:didFinishWithImage:forURL:userInfo:), self, image, downloader.url, userInfo); 460 | } 461 | #if NS_BLOCKS_AVAILABLE 462 | if ([[downloadInfo objectAtIndex:uidx] objectForKey:@"success"]) 463 | { 464 | SDWebImageSuccessBlock success = [[downloadInfo objectAtIndex:uidx] objectForKey:@"success"]; 465 | success(image, NO); 466 | } 467 | #endif 468 | } 469 | else 470 | { 471 | if ([delegate respondsToSelector:@selector(webImageManager:didFailWithError:)]) 472 | { 473 | [delegate performSelector:@selector(webImageManager:didFailWithError:) withObject:self withObject:nil]; 474 | } 475 | if ([delegate respondsToSelector:@selector(webImageManager:didFailWithError:forURL:)]) 476 | { 477 | objc_msgSend(delegate, @selector(webImageManager:didFailWithError:forURL:), self, nil, downloader.url); 478 | } 479 | if ([delegate respondsToSelector:@selector(webImageManager:didFailWithError:forURL:userInfo:)]) 480 | { 481 | NSDictionary *userInfo = [[downloadInfo objectAtIndex:uidx] objectForKey:@"userInfo"]; 482 | if ([userInfo isKindOfClass:NSNull.class]) 483 | { 484 | userInfo = nil; 485 | } 486 | objc_msgSend(delegate, @selector(webImageManager:didFailWithError:forURL:userInfo:), self, nil, downloader.url, userInfo); 487 | } 488 | #if NS_BLOCKS_AVAILABLE 489 | if ([[downloadInfo objectAtIndex:uidx] objectForKey:@"failure"]) 490 | { 491 | SDWebImageFailureBlock failure = [[downloadInfo objectAtIndex:uidx] objectForKey:@"failure"]; 492 | failure(nil); 493 | } 494 | #endif 495 | } 496 | 497 | [downloaders removeObjectAtIndex:uidx]; 498 | [downloadInfo removeObjectAtIndex:uidx]; 499 | [downloadDelegates removeObjectAtIndex:uidx]; 500 | } 501 | } 502 | 503 | if (image) 504 | { 505 | 506 | NSString *cacheKey = [self cacheKeyForURL:downloader.url andDictionary:downloader.userInfo]; 507 | 508 | 509 | // Store the image in the cache 510 | [[SDImageCache sharedImageCache] storeImage:image 511 | imageData:downloader.imageData 512 | forKey: cacheKey 513 | toDisk:!(options & SDWebImageCacheMemoryOnly)]; 514 | } 515 | else if (!(options & SDWebImageRetryFailed)) 516 | { 517 | // The image can't be downloaded from this URL, mark the URL as failed so we won't try and fail again and again 518 | // (do this only if SDWebImageRetryFailed isn't activated) 519 | [failedURLs addObject:downloader.url]; 520 | } 521 | 522 | 523 | // Release the downloader 524 | NSString *downloaderkey = [self cacheKeyForURL:downloader.url andDictionary:downloader.userInfo]; 525 | [downloaderForURL removeObjectForKey:downloaderkey]; 526 | SDWIRelease(downloader); 527 | } 528 | 529 | - (void)imageDownloader:(SDWebImageDownloader *)downloader didFailWithError:(NSError *)error; 530 | { 531 | SDWIRetain(downloader); 532 | 533 | // Notify all the downloadDelegates with this downloader 534 | for (NSInteger idx = (NSInteger)[downloaders count] - 1; idx >= 0; idx--) 535 | { 536 | NSUInteger uidx = (NSUInteger)idx; 537 | SDWebImageDownloader *aDownloader = [downloaders objectAtIndex:uidx]; 538 | if (aDownloader == downloader) 539 | { 540 | id delegate = [downloadDelegates objectAtIndex:uidx]; 541 | SDWIRetain(delegate); 542 | SDWIAutorelease(delegate); 543 | 544 | if ([delegate respondsToSelector:@selector(webImageManager:didFailWithError:)]) 545 | { 546 | [delegate performSelector:@selector(webImageManager:didFailWithError:) withObject:self withObject:error]; 547 | } 548 | if ([delegate respondsToSelector:@selector(webImageManager:didFailWithError:forURL:)]) 549 | { 550 | objc_msgSend(delegate, @selector(webImageManager:didFailWithError:forURL:), self, error, downloader.url); 551 | } 552 | if ([delegate respondsToSelector:@selector(webImageManager:didFailWithError:forURL:userInfo:)]) 553 | { 554 | NSDictionary *userInfo = [[downloadInfo objectAtIndex:uidx] objectForKey:@"userInfo"]; 555 | if ([userInfo isKindOfClass:NSNull.class]) 556 | { 557 | userInfo = nil; 558 | } 559 | objc_msgSend(delegate, @selector(webImageManager:didFailWithError:forURL:userInfo:), self, error, downloader.url, userInfo); 560 | } 561 | #if NS_BLOCKS_AVAILABLE 562 | if ([[downloadInfo objectAtIndex:uidx] objectForKey:@"failure"]) 563 | { 564 | SDWebImageFailureBlock failure = [[downloadInfo objectAtIndex:uidx] objectForKey:@"failure"]; 565 | failure(error); 566 | } 567 | #endif 568 | 569 | [downloaders removeObjectAtIndex:uidx]; 570 | [downloadInfo removeObjectAtIndex:uidx]; 571 | [downloadDelegates removeObjectAtIndex:uidx]; 572 | } 573 | } 574 | 575 | // Release the downloader 576 | NSString *downloaderkey = [self cacheKeyForURL:downloader.url andDictionary:downloader.userInfo]; 577 | [downloaderForURL removeObjectForKey:downloaderkey]; 578 | SDWIRelease(downloader); 579 | } 580 | 581 | @end 582 | -------------------------------------------------------------------------------- /Image Cache Resize.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | AB2CD95B163AE46A00EA290F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB2CD95A163AE46A00EA290F /* UIKit.framework */; }; 11 | AB2CD95D163AE46A00EA290F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB2CD95C163AE46A00EA290F /* Foundation.framework */; }; 12 | AB2CD95F163AE46A00EA290F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB2CD95E163AE46A00EA290F /* CoreGraphics.framework */; }; 13 | AB2CD965163AE46A00EA290F /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = AB2CD963163AE46A00EA290F /* InfoPlist.strings */; }; 14 | AB2CD967163AE46A00EA290F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = AB2CD966163AE46A00EA290F /* main.m */; }; 15 | AB2CD96B163AE46A00EA290F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AB2CD96A163AE46A00EA290F /* AppDelegate.m */; }; 16 | AB2CD96D163AE46A00EA290F /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = AB2CD96C163AE46A00EA290F /* Default.png */; }; 17 | AB2CD96F163AE46A00EA290F /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AB2CD96E163AE46A00EA290F /* Default@2x.png */; }; 18 | AB2CD971163AE46A00EA290F /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = AB2CD970163AE46A00EA290F /* Default-568h@2x.png */; }; 19 | AB2CD974163AE46A00EA290F /* MainStoryboard_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AB2CD972163AE46A00EA290F /* MainStoryboard_iPhone.storyboard */; }; 20 | AB2CD97A163AE46A00EA290F /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AB2CD979163AE46A00EA290F /* ViewController.m */; }; 21 | AB2CD9A2163AE9A600EA290F /* MKAnnotationView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = AB2CD986163AE9A600EA290F /* MKAnnotationView+WebCache.m */; }; 22 | AB2CD9A3163AE9A600EA290F /* SDImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = AB2CD988163AE9A600EA290F /* SDImageCache.m */; }; 23 | AB2CD9A4163AE9A600EA290F /* SDWebImageDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = AB2CD98C163AE9A600EA290F /* SDWebImageDecoder.m */; }; 24 | AB2CD9A5163AE9A600EA290F /* SDWebImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = AB2CD98E163AE9A600EA290F /* SDWebImageDownloader.m */; }; 25 | AB2CD9A6163AE9A600EA290F /* SDWebImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = AB2CD991163AE9A600EA290F /* SDWebImageManager.m */; }; 26 | AB2CD9A7163AE9A600EA290F /* SDWebImagePrefetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = AB2CD994163AE9A600EA290F /* SDWebImagePrefetcher.m */; }; 27 | AB2CD9A8163AE9A600EA290F /* UIButton+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = AB2CD996163AE9A600EA290F /* UIButton+WebCache.m */; }; 28 | AB2CD9A9163AE9A600EA290F /* UIImageView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = AB2CD998163AE9A600EA290F /* UIImageView+WebCache.m */; }; 29 | AB2CD9AA163AE9A600EA290F /* UIImage+Alpha.m in Sources */ = {isa = PBXBuildFile; fileRef = AB2CD99B163AE9A600EA290F /* UIImage+Alpha.m */; }; 30 | AB2CD9AB163AE9A600EA290F /* UIImage+Resize.m in Sources */ = {isa = PBXBuildFile; fileRef = AB2CD99D163AE9A600EA290F /* UIImage+Resize.m */; }; 31 | AB2CD9AC163AE9A600EA290F /* UIImage+RoundedCorner.m in Sources */ = {isa = PBXBuildFile; fileRef = AB2CD99F163AE9A600EA290F /* UIImage+RoundedCorner.m */; }; 32 | AB2CD9AD163AE9A600EA290F /* UIImage+Scaling.m in Sources */ = {isa = PBXBuildFile; fileRef = AB2CD9A1163AE9A600EA290F /* UIImage+Scaling.m */; }; 33 | AB2CD9AF163AE9E500EA290F /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB2CD9AE163AE9E500EA290F /* ImageIO.framework */; }; 34 | AB2CD9B1163AEACC00EA290F /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB2CD9B0163AEACC00EA290F /* MapKit.framework */; }; 35 | /* End PBXBuildFile section */ 36 | 37 | /* Begin PBXFileReference section */ 38 | AB2CD956163AE46A00EA290F /* Image Cache Resize.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Image Cache Resize.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | AB2CD95A163AE46A00EA290F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 40 | AB2CD95C163AE46A00EA290F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 41 | AB2CD95E163AE46A00EA290F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 42 | AB2CD962163AE46A00EA290F /* Image Cache Resize-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Image Cache Resize-Info.plist"; sourceTree = ""; }; 43 | AB2CD964163AE46A00EA290F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 44 | AB2CD966163AE46A00EA290F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 45 | AB2CD968163AE46A00EA290F /* Image Cache Resize-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Image Cache Resize-Prefix.pch"; sourceTree = ""; }; 46 | AB2CD969163AE46A00EA290F /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 47 | AB2CD96A163AE46A00EA290F /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 48 | AB2CD96C163AE46A00EA290F /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 49 | AB2CD96E163AE46A00EA290F /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 50 | AB2CD970163AE46A00EA290F /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 51 | AB2CD973163AE46A00EA290F /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard_iPhone.storyboard; sourceTree = ""; }; 52 | AB2CD978163AE46A00EA290F /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 53 | AB2CD979163AE46A00EA290F /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 54 | AB2CD985163AE9A600EA290F /* MKAnnotationView+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MKAnnotationView+WebCache.h"; sourceTree = ""; }; 55 | AB2CD986163AE9A600EA290F /* MKAnnotationView+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MKAnnotationView+WebCache.m"; sourceTree = ""; }; 56 | AB2CD987163AE9A600EA290F /* SDImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDImageCache.h; sourceTree = ""; }; 57 | AB2CD988163AE9A600EA290F /* SDImageCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDImageCache.m; sourceTree = ""; }; 58 | AB2CD989163AE9A600EA290F /* SDImageCacheDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDImageCacheDelegate.h; sourceTree = ""; }; 59 | AB2CD98A163AE9A600EA290F /* SDWebImageCompat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageCompat.h; sourceTree = ""; }; 60 | AB2CD98B163AE9A600EA290F /* SDWebImageDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageDecoder.h; sourceTree = ""; }; 61 | AB2CD98C163AE9A600EA290F /* SDWebImageDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageDecoder.m; sourceTree = ""; }; 62 | AB2CD98D163AE9A600EA290F /* SDWebImageDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageDownloader.h; sourceTree = ""; }; 63 | AB2CD98E163AE9A600EA290F /* SDWebImageDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageDownloader.m; sourceTree = ""; }; 64 | AB2CD98F163AE9A600EA290F /* SDWebImageDownloaderDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageDownloaderDelegate.h; sourceTree = ""; }; 65 | AB2CD990163AE9A600EA290F /* SDWebImageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageManager.h; sourceTree = ""; }; 66 | AB2CD991163AE9A600EA290F /* SDWebImageManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageManager.m; sourceTree = ""; }; 67 | AB2CD992163AE9A600EA290F /* SDWebImageManagerDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageManagerDelegate.h; sourceTree = ""; }; 68 | AB2CD993163AE9A600EA290F /* SDWebImagePrefetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImagePrefetcher.h; sourceTree = ""; }; 69 | AB2CD994163AE9A600EA290F /* SDWebImagePrefetcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImagePrefetcher.m; sourceTree = ""; }; 70 | AB2CD995163AE9A600EA290F /* UIButton+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIButton+WebCache.h"; sourceTree = ""; }; 71 | AB2CD996163AE9A600EA290F /* UIButton+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIButton+WebCache.m"; sourceTree = ""; }; 72 | AB2CD997163AE9A600EA290F /* UIImageView+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImageView+WebCache.h"; sourceTree = ""; }; 73 | AB2CD998163AE9A600EA290F /* UIImageView+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImageView+WebCache.m"; sourceTree = ""; }; 74 | AB2CD99A163AE9A600EA290F /* UIImage+Alpha.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Alpha.h"; sourceTree = ""; }; 75 | AB2CD99B163AE9A600EA290F /* UIImage+Alpha.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Alpha.m"; sourceTree = ""; }; 76 | AB2CD99C163AE9A600EA290F /* UIImage+Resize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Resize.h"; sourceTree = ""; }; 77 | AB2CD99D163AE9A600EA290F /* UIImage+Resize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Resize.m"; sourceTree = ""; }; 78 | AB2CD99E163AE9A600EA290F /* UIImage+RoundedCorner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+RoundedCorner.h"; sourceTree = ""; }; 79 | AB2CD99F163AE9A600EA290F /* UIImage+RoundedCorner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+RoundedCorner.m"; sourceTree = ""; }; 80 | AB2CD9A0163AE9A600EA290F /* UIImage+Scaling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Scaling.h"; sourceTree = ""; }; 81 | AB2CD9A1163AE9A600EA290F /* UIImage+Scaling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Scaling.m"; sourceTree = ""; }; 82 | AB2CD9AE163AE9E500EA290F /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; }; 83 | AB2CD9B0163AEACC00EA290F /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; 84 | /* End PBXFileReference section */ 85 | 86 | /* Begin PBXFrameworksBuildPhase section */ 87 | AB2CD953163AE46A00EA290F /* Frameworks */ = { 88 | isa = PBXFrameworksBuildPhase; 89 | buildActionMask = 2147483647; 90 | files = ( 91 | AB2CD9B1163AEACC00EA290F /* MapKit.framework in Frameworks */, 92 | AB2CD9AF163AE9E500EA290F /* ImageIO.framework in Frameworks */, 93 | AB2CD95B163AE46A00EA290F /* UIKit.framework in Frameworks */, 94 | AB2CD95D163AE46A00EA290F /* Foundation.framework in Frameworks */, 95 | AB2CD95F163AE46A00EA290F /* CoreGraphics.framework in Frameworks */, 96 | ); 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | /* End PBXFrameworksBuildPhase section */ 100 | 101 | /* Begin PBXGroup section */ 102 | AB2CD94B163AE46A00EA290F = { 103 | isa = PBXGroup; 104 | children = ( 105 | AB2CD960163AE46A00EA290F /* Image Cache Resize */, 106 | AB2CD959163AE46A00EA290F /* Frameworks */, 107 | AB2CD957163AE46A00EA290F /* Products */, 108 | ); 109 | sourceTree = ""; 110 | }; 111 | AB2CD957163AE46A00EA290F /* Products */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | AB2CD956163AE46A00EA290F /* Image Cache Resize.app */, 115 | ); 116 | name = Products; 117 | sourceTree = ""; 118 | }; 119 | AB2CD959163AE46A00EA290F /* Frameworks */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | AB2CD9B0163AEACC00EA290F /* MapKit.framework */, 123 | AB2CD9AE163AE9E500EA290F /* ImageIO.framework */, 124 | AB2CD95A163AE46A00EA290F /* UIKit.framework */, 125 | AB2CD95C163AE46A00EA290F /* Foundation.framework */, 126 | AB2CD95E163AE46A00EA290F /* CoreGraphics.framework */, 127 | ); 128 | name = Frameworks; 129 | sourceTree = ""; 130 | }; 131 | AB2CD960163AE46A00EA290F /* Image Cache Resize */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | AB2CD983163AE9A600EA290F /* Libraries */, 135 | AB2CD969163AE46A00EA290F /* AppDelegate.h */, 136 | AB2CD96A163AE46A00EA290F /* AppDelegate.m */, 137 | AB2CD972163AE46A00EA290F /* MainStoryboard_iPhone.storyboard */, 138 | AB2CD978163AE46A00EA290F /* ViewController.h */, 139 | AB2CD979163AE46A00EA290F /* ViewController.m */, 140 | AB2CD961163AE46A00EA290F /* Supporting Files */, 141 | ); 142 | path = "Image Cache Resize"; 143 | sourceTree = ""; 144 | }; 145 | AB2CD961163AE46A00EA290F /* Supporting Files */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | AB2CD962163AE46A00EA290F /* Image Cache Resize-Info.plist */, 149 | AB2CD963163AE46A00EA290F /* InfoPlist.strings */, 150 | AB2CD966163AE46A00EA290F /* main.m */, 151 | AB2CD968163AE46A00EA290F /* Image Cache Resize-Prefix.pch */, 152 | AB2CD96C163AE46A00EA290F /* Default.png */, 153 | AB2CD96E163AE46A00EA290F /* Default@2x.png */, 154 | AB2CD970163AE46A00EA290F /* Default-568h@2x.png */, 155 | ); 156 | name = "Supporting Files"; 157 | sourceTree = ""; 158 | }; 159 | AB2CD983163AE9A600EA290F /* Libraries */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | AB2CD984163AE9A600EA290F /* SDWebImage */, 163 | AB2CD999163AE9A600EA290F /* UIImage+Resize */, 164 | ); 165 | path = Libraries; 166 | sourceTree = ""; 167 | }; 168 | AB2CD984163AE9A600EA290F /* SDWebImage */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | AB2CD985163AE9A600EA290F /* MKAnnotationView+WebCache.h */, 172 | AB2CD986163AE9A600EA290F /* MKAnnotationView+WebCache.m */, 173 | AB2CD987163AE9A600EA290F /* SDImageCache.h */, 174 | AB2CD988163AE9A600EA290F /* SDImageCache.m */, 175 | AB2CD989163AE9A600EA290F /* SDImageCacheDelegate.h */, 176 | AB2CD98A163AE9A600EA290F /* SDWebImageCompat.h */, 177 | AB2CD98B163AE9A600EA290F /* SDWebImageDecoder.h */, 178 | AB2CD98C163AE9A600EA290F /* SDWebImageDecoder.m */, 179 | AB2CD98D163AE9A600EA290F /* SDWebImageDownloader.h */, 180 | AB2CD98E163AE9A600EA290F /* SDWebImageDownloader.m */, 181 | AB2CD98F163AE9A600EA290F /* SDWebImageDownloaderDelegate.h */, 182 | AB2CD990163AE9A600EA290F /* SDWebImageManager.h */, 183 | AB2CD991163AE9A600EA290F /* SDWebImageManager.m */, 184 | AB2CD992163AE9A600EA290F /* SDWebImageManagerDelegate.h */, 185 | AB2CD993163AE9A600EA290F /* SDWebImagePrefetcher.h */, 186 | AB2CD994163AE9A600EA290F /* SDWebImagePrefetcher.m */, 187 | AB2CD995163AE9A600EA290F /* UIButton+WebCache.h */, 188 | AB2CD996163AE9A600EA290F /* UIButton+WebCache.m */, 189 | AB2CD997163AE9A600EA290F /* UIImageView+WebCache.h */, 190 | AB2CD998163AE9A600EA290F /* UIImageView+WebCache.m */, 191 | ); 192 | path = SDWebImage; 193 | sourceTree = ""; 194 | }; 195 | AB2CD999163AE9A600EA290F /* UIImage+Resize */ = { 196 | isa = PBXGroup; 197 | children = ( 198 | AB2CD99A163AE9A600EA290F /* UIImage+Alpha.h */, 199 | AB2CD99B163AE9A600EA290F /* UIImage+Alpha.m */, 200 | AB2CD99C163AE9A600EA290F /* UIImage+Resize.h */, 201 | AB2CD99D163AE9A600EA290F /* UIImage+Resize.m */, 202 | AB2CD99E163AE9A600EA290F /* UIImage+RoundedCorner.h */, 203 | AB2CD99F163AE9A600EA290F /* UIImage+RoundedCorner.m */, 204 | AB2CD9A0163AE9A600EA290F /* UIImage+Scaling.h */, 205 | AB2CD9A1163AE9A600EA290F /* UIImage+Scaling.m */, 206 | ); 207 | path = "UIImage+Resize"; 208 | sourceTree = ""; 209 | }; 210 | /* End PBXGroup section */ 211 | 212 | /* Begin PBXNativeTarget section */ 213 | AB2CD955163AE46A00EA290F /* Image Cache Resize */ = { 214 | isa = PBXNativeTarget; 215 | buildConfigurationList = AB2CD97D163AE46A00EA290F /* Build configuration list for PBXNativeTarget "Image Cache Resize" */; 216 | buildPhases = ( 217 | AB2CD952163AE46A00EA290F /* Sources */, 218 | AB2CD953163AE46A00EA290F /* Frameworks */, 219 | AB2CD954163AE46A00EA290F /* Resources */, 220 | ); 221 | buildRules = ( 222 | ); 223 | dependencies = ( 224 | ); 225 | name = "Image Cache Resize"; 226 | productName = "Image Cache Resize"; 227 | productReference = AB2CD956163AE46A00EA290F /* Image Cache Resize.app */; 228 | productType = "com.apple.product-type.application"; 229 | }; 230 | /* End PBXNativeTarget section */ 231 | 232 | /* Begin PBXProject section */ 233 | AB2CD94D163AE46A00EA290F /* Project object */ = { 234 | isa = PBXProject; 235 | attributes = { 236 | LastUpgradeCheck = 0450; 237 | ORGANIZATIONNAME = TopTier; 238 | }; 239 | buildConfigurationList = AB2CD950163AE46A00EA290F /* Build configuration list for PBXProject "Image Cache Resize" */; 240 | compatibilityVersion = "Xcode 3.2"; 241 | developmentRegion = English; 242 | hasScannedForEncodings = 0; 243 | knownRegions = ( 244 | en, 245 | ); 246 | mainGroup = AB2CD94B163AE46A00EA290F; 247 | productRefGroup = AB2CD957163AE46A00EA290F /* Products */; 248 | projectDirPath = ""; 249 | projectRoot = ""; 250 | targets = ( 251 | AB2CD955163AE46A00EA290F /* Image Cache Resize */, 252 | ); 253 | }; 254 | /* End PBXProject section */ 255 | 256 | /* Begin PBXResourcesBuildPhase section */ 257 | AB2CD954163AE46A00EA290F /* Resources */ = { 258 | isa = PBXResourcesBuildPhase; 259 | buildActionMask = 2147483647; 260 | files = ( 261 | AB2CD965163AE46A00EA290F /* InfoPlist.strings in Resources */, 262 | AB2CD96D163AE46A00EA290F /* Default.png in Resources */, 263 | AB2CD96F163AE46A00EA290F /* Default@2x.png in Resources */, 264 | AB2CD971163AE46A00EA290F /* Default-568h@2x.png in Resources */, 265 | AB2CD974163AE46A00EA290F /* MainStoryboard_iPhone.storyboard in Resources */, 266 | ); 267 | runOnlyForDeploymentPostprocessing = 0; 268 | }; 269 | /* End PBXResourcesBuildPhase section */ 270 | 271 | /* Begin PBXSourcesBuildPhase section */ 272 | AB2CD952163AE46A00EA290F /* Sources */ = { 273 | isa = PBXSourcesBuildPhase; 274 | buildActionMask = 2147483647; 275 | files = ( 276 | AB2CD967163AE46A00EA290F /* main.m in Sources */, 277 | AB2CD96B163AE46A00EA290F /* AppDelegate.m in Sources */, 278 | AB2CD97A163AE46A00EA290F /* ViewController.m in Sources */, 279 | AB2CD9A2163AE9A600EA290F /* MKAnnotationView+WebCache.m in Sources */, 280 | AB2CD9A3163AE9A600EA290F /* SDImageCache.m in Sources */, 281 | AB2CD9A4163AE9A600EA290F /* SDWebImageDecoder.m in Sources */, 282 | AB2CD9A5163AE9A600EA290F /* SDWebImageDownloader.m in Sources */, 283 | AB2CD9A6163AE9A600EA290F /* SDWebImageManager.m in Sources */, 284 | AB2CD9A7163AE9A600EA290F /* SDWebImagePrefetcher.m in Sources */, 285 | AB2CD9A8163AE9A600EA290F /* UIButton+WebCache.m in Sources */, 286 | AB2CD9A9163AE9A600EA290F /* UIImageView+WebCache.m in Sources */, 287 | AB2CD9AA163AE9A600EA290F /* UIImage+Alpha.m in Sources */, 288 | AB2CD9AB163AE9A600EA290F /* UIImage+Resize.m in Sources */, 289 | AB2CD9AC163AE9A600EA290F /* UIImage+RoundedCorner.m in Sources */, 290 | AB2CD9AD163AE9A600EA290F /* UIImage+Scaling.m in Sources */, 291 | ); 292 | runOnlyForDeploymentPostprocessing = 0; 293 | }; 294 | /* End PBXSourcesBuildPhase section */ 295 | 296 | /* Begin PBXVariantGroup section */ 297 | AB2CD963163AE46A00EA290F /* InfoPlist.strings */ = { 298 | isa = PBXVariantGroup; 299 | children = ( 300 | AB2CD964163AE46A00EA290F /* en */, 301 | ); 302 | name = InfoPlist.strings; 303 | sourceTree = ""; 304 | }; 305 | AB2CD972163AE46A00EA290F /* MainStoryboard_iPhone.storyboard */ = { 306 | isa = PBXVariantGroup; 307 | children = ( 308 | AB2CD973163AE46A00EA290F /* en */, 309 | ); 310 | name = MainStoryboard_iPhone.storyboard; 311 | sourceTree = ""; 312 | }; 313 | /* End PBXVariantGroup section */ 314 | 315 | /* Begin XCBuildConfiguration section */ 316 | AB2CD97B163AE46A00EA290F /* Debug */ = { 317 | isa = XCBuildConfiguration; 318 | buildSettings = { 319 | ALWAYS_SEARCH_USER_PATHS = NO; 320 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 321 | CLANG_CXX_LIBRARY = "libc++"; 322 | CLANG_ENABLE_OBJC_ARC = YES; 323 | CLANG_WARN_EMPTY_BODY = YES; 324 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 325 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 326 | COPY_PHASE_STRIP = NO; 327 | GCC_C_LANGUAGE_STANDARD = gnu99; 328 | GCC_DYNAMIC_NO_PIC = NO; 329 | GCC_OPTIMIZATION_LEVEL = 0; 330 | GCC_PREPROCESSOR_DEFINITIONS = ( 331 | "DEBUG=1", 332 | "$(inherited)", 333 | ); 334 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 335 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 336 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 337 | GCC_WARN_UNUSED_VARIABLE = YES; 338 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 339 | ONLY_ACTIVE_ARCH = YES; 340 | SDKROOT = iphoneos; 341 | TARGETED_DEVICE_FAMILY = "1,2"; 342 | }; 343 | name = Debug; 344 | }; 345 | AB2CD97C163AE46A00EA290F /* Release */ = { 346 | isa = XCBuildConfiguration; 347 | buildSettings = { 348 | ALWAYS_SEARCH_USER_PATHS = NO; 349 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 350 | CLANG_CXX_LIBRARY = "libc++"; 351 | CLANG_ENABLE_OBJC_ARC = YES; 352 | CLANG_WARN_EMPTY_BODY = YES; 353 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 354 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 355 | COPY_PHASE_STRIP = YES; 356 | GCC_C_LANGUAGE_STANDARD = gnu99; 357 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 358 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 359 | GCC_WARN_UNUSED_VARIABLE = YES; 360 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 361 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 362 | SDKROOT = iphoneos; 363 | TARGETED_DEVICE_FAMILY = "1,2"; 364 | VALIDATE_PRODUCT = YES; 365 | }; 366 | name = Release; 367 | }; 368 | AB2CD97E163AE46A00EA290F /* Debug */ = { 369 | isa = XCBuildConfiguration; 370 | buildSettings = { 371 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 372 | GCC_PREFIX_HEADER = "Image Cache Resize/Image Cache Resize-Prefix.pch"; 373 | INFOPLIST_FILE = "Image Cache Resize/Image Cache Resize-Info.plist"; 374 | PRODUCT_NAME = "$(TARGET_NAME)"; 375 | TARGETED_DEVICE_FAMILY = 1; 376 | WRAPPER_EXTENSION = app; 377 | }; 378 | name = Debug; 379 | }; 380 | AB2CD97F163AE46A00EA290F /* Release */ = { 381 | isa = XCBuildConfiguration; 382 | buildSettings = { 383 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 384 | GCC_PREFIX_HEADER = "Image Cache Resize/Image Cache Resize-Prefix.pch"; 385 | INFOPLIST_FILE = "Image Cache Resize/Image Cache Resize-Info.plist"; 386 | PRODUCT_NAME = "$(TARGET_NAME)"; 387 | TARGETED_DEVICE_FAMILY = 1; 388 | WRAPPER_EXTENSION = app; 389 | }; 390 | name = Release; 391 | }; 392 | /* End XCBuildConfiguration section */ 393 | 394 | /* Begin XCConfigurationList section */ 395 | AB2CD950163AE46A00EA290F /* Build configuration list for PBXProject "Image Cache Resize" */ = { 396 | isa = XCConfigurationList; 397 | buildConfigurations = ( 398 | AB2CD97B163AE46A00EA290F /* Debug */, 399 | AB2CD97C163AE46A00EA290F /* Release */, 400 | ); 401 | defaultConfigurationIsVisible = 0; 402 | defaultConfigurationName = Release; 403 | }; 404 | AB2CD97D163AE46A00EA290F /* Build configuration list for PBXNativeTarget "Image Cache Resize" */ = { 405 | isa = XCConfigurationList; 406 | buildConfigurations = ( 407 | AB2CD97E163AE46A00EA290F /* Debug */, 408 | AB2CD97F163AE46A00EA290F /* Release */, 409 | ); 410 | defaultConfigurationIsVisible = 0; 411 | defaultConfigurationName = Release; 412 | }; 413 | /* End XCConfigurationList section */ 414 | }; 415 | rootObject = AB2CD94D163AE46A00EA290F /* Project object */; 416 | } 417 | --------------------------------------------------------------------------------