UIImage+Additions.m 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. //
  2. // UIImage+Additions.m
  3. // Created by Joan Martin.
  4. // Take a look to my repos at http://github.com/vilanovi
  5. //
  6. // Copyright (c) 2013 Joan Martin, vilanovi@gmail.com.
  7. //
  8. // Permission is hereby granted, free of charge, to any person obtaining a copy
  9. // of this software and associated documentation files (the "Software"), to deal
  10. // in the Software without restriction, including without limitation the rights to
  11. // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  12. // of the Software, and to permit persons to whom the Software is furnished to do
  13. // so, subject to the following conditions:
  14. //
  15. // The above copyright notice and this permission notice shall be included in all
  16. // copies or substantial portions of the Software.
  17. //
  18. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  19. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  20. // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  21. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  23. // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
  24. #import "UIImage+Additions.h"
  25. @interface NSString (MD5Hashing)
  26. - (NSString*)md5;
  27. @end
  28. #import <CommonCrypto/CommonDigest.h>
  29. @implementation NSString (MD5Hashing)
  30. - (NSString *)md5
  31. {
  32. const char *cStr = [self UTF8String];
  33. unsigned char result[16];
  34. CC_MD5(cStr, (CC_LONG)strlen(cStr), result);
  35. return [NSString stringWithFormat:
  36. @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
  37. result[0], result[1], result[2], result[3],
  38. result[4], result[5], result[6], result[7],
  39. result[8], result[9], result[10], result[11],
  40. result[12], result[13], result[14], result[15]
  41. ];
  42. }
  43. @end
  44. const UICornerInset UICornerInsetZero = {0.0f, 0.0f, 0.0f, 0.0f};
  45. NSString* NSStringFromUICornerInset(UICornerInset cornerInset)
  46. {
  47. return [NSString stringWithFormat:@"UICornerInset <topLeft:%f> <topRight:%f> <bottomLeft:%f> <bottomRight:%f>",cornerInset.topLeft, cornerInset.topRight, cornerInset.bottomLeft, cornerInset.bottomRight];
  48. }
  49. static NSCache * _imageCache = nil;
  50. static NSString * kUIImageName = @"kUIImageName";
  51. static NSString * kUIImageResizableImage = @"kUIImageResizableImage";
  52. static NSString * kUIImageColors = @"kUIImageColors";
  53. static NSString * kUIImageTintColor = @"kUIImageTintColor";
  54. static NSString * kUIImageTintStyle = @"kUIImageTintStyle";
  55. static NSString * kUIImageCornerInset = @"kUIImageCornerInset";
  56. static NSString * kUIImageGradientDirection = @"kUIImageGradientDirection";
  57. static NSString * kUIImageSize = @"kUIImageSize";
  58. @implementation UIImage (Additions)
  59. + (UIImage*)imageWithColor:(UIColor*)color size:(CGSize)size
  60. {
  61. return [self imageWithColor:color size:size cornerInset:UICornerInsetZero];
  62. }
  63. + (UIImage*)imageWithColor:(UIColor*)color size:(CGSize)size cornerRadius:(CGFloat)cornerRadius
  64. {
  65. return [self imageWithColor:color size:size cornerInset:UICornerInsetMake(cornerRadius, cornerRadius, cornerRadius, cornerRadius)];
  66. }
  67. + (UIImage*)imageWithColor:(UIColor*)color size:(CGSize)size cornerInset:(UICornerInset)cornerInset
  68. {
  69. return [self _imageWithColor:color size:size cornerInset:cornerInset saveInCache:YES];
  70. }
  71. + (UIImage*)resizableImageWithColor:(UIColor*)color
  72. {
  73. return [self resizableImageWithColor:color cornerInset:UICornerInsetZero];
  74. }
  75. + (UIImage*)resizableImageWithColor:(UIColor*)color cornerRadius:(CGFloat)cornerRadius
  76. {
  77. return [self resizableImageWithColor:color cornerInset:UICornerInsetMake(cornerRadius, cornerRadius, cornerRadius, cornerRadius)];
  78. }
  79. + (UIImage*)resizableImageWithColor:(UIColor*)color cornerInset:(UICornerInset)cornerInset
  80. {
  81. if (!color)
  82. return nil;
  83. NSDictionary *descriptors = @{kUIImageColors : @[color],
  84. kUIImageResizableImage : @YES,
  85. kUIImageCornerInset : [NSValue valueWithUICornerInset:cornerInset]};
  86. UIImage *image = [self _cachedImageWithDescriptors:descriptors];
  87. if (image)
  88. return image;
  89. CGSize size = CGSizeMake(MAX(cornerInset.topLeft, cornerInset.bottomLeft) + MAX(cornerInset.topRight, cornerInset.bottomRight) + 1,
  90. MAX(cornerInset.topLeft, cornerInset.topRight) + MAX(cornerInset.bottomLeft, cornerInset.bottomRight) + 1);
  91. UIEdgeInsets capInsets = UIEdgeInsetsMake(MAX(cornerInset.topLeft, cornerInset.topRight),
  92. MAX(cornerInset.topLeft, cornerInset.bottomLeft),
  93. MAX(cornerInset.bottomLeft, cornerInset.bottomRight),
  94. MAX(cornerInset.topRight, cornerInset.bottomRight));
  95. image = [[self imageWithColor:color size:size cornerInset:cornerInset] resizableImageWithCapInsets:capInsets];
  96. [self _cacheImage:image withDescriptors:descriptors];
  97. return image;
  98. }
  99. + (UIImage*)blackColorImage
  100. {
  101. return [self resizableImageWithColor:[UIColor blackColor]];
  102. }
  103. + (UIImage*)darkGrayColorImage
  104. {
  105. return [self resizableImageWithColor:[UIColor darkGrayColor]];
  106. }
  107. + (UIImage*)lightGrayColorImage
  108. {
  109. return [self resizableImageWithColor:[UIColor lightGrayColor]];
  110. }
  111. + (UIImage*)whiteColorImage
  112. {
  113. return [self resizableImageWithColor:[UIColor whiteColor]];
  114. }
  115. + (UIImage*)grayColorImage
  116. {
  117. return [self resizableImageWithColor:[UIColor grayColor]];
  118. }
  119. + (UIImage*)redColorImage
  120. {
  121. return [self resizableImageWithColor:[UIColor redColor]];
  122. }
  123. + (UIImage*)greenColorImage
  124. {
  125. return [self resizableImageWithColor:[UIColor greenColor]];
  126. }
  127. + (UIImage*)blueColorImage
  128. {
  129. return [self resizableImageWithColor:[UIColor blueColor]];
  130. }
  131. + (UIImage*)cyanColorImage
  132. {
  133. return [self resizableImageWithColor:[UIColor cyanColor]];
  134. }
  135. + (UIImage*)yellowColorImage
  136. {
  137. return [self resizableImageWithColor:[UIColor yellowColor]];
  138. }
  139. + (UIImage*)magentaColorImage
  140. {
  141. return [self resizableImageWithColor:[UIColor magentaColor]];
  142. }
  143. + (UIImage*)orangeColorImage
  144. {
  145. return [self resizableImageWithColor:[UIColor orangeColor]];
  146. }
  147. + (UIImage*)purpleColorImage
  148. {
  149. return [self resizableImageWithColor:[UIColor purpleColor]];
  150. }
  151. + (UIImage*)brownColorImage
  152. {
  153. return [self resizableImageWithColor:[UIColor brownColor]];
  154. }
  155. + (UIImage*)clearColorImage
  156. {
  157. return [self resizableImageWithColor:[UIColor clearColor]];
  158. }
  159. + (UIImage*)imageNamed:(NSString *)name tintColor:(UIColor*)color style:(UIImageTintedStyle)tintStyle
  160. {
  161. if (!name)
  162. return nil;
  163. UIImage *image = [UIImage imageNamed:name];
  164. if (!image)
  165. return nil;
  166. if (!color)
  167. return image;
  168. NSDictionary *descriptors = @{kUIImageName : name,
  169. kUIImageTintColor : color,
  170. kUIImageTintStyle : @(tintStyle)};
  171. UIImage *tintedImage = [self _cachedImageWithDescriptors:descriptors];
  172. if (!tintedImage)
  173. {
  174. tintedImage = [image tintedImageWithColor:color style:tintStyle];
  175. [self _cacheImage:tintedImage withDescriptors:descriptors];
  176. }
  177. return tintedImage;
  178. }
  179. - (UIImage*)tintedImageWithColor:(UIColor*)color style:(UIImageTintedStyle)tintStyle
  180. {
  181. if (!color)
  182. return self;
  183. CGFloat scale = self.scale;
  184. CGSize size = CGSizeMake(scale * self.size.width, scale * self.size.height);
  185. UIGraphicsBeginImageContext(size);
  186. CGContextRef context = UIGraphicsGetCurrentContext();
  187. CGContextTranslateCTM(context, 0, size.height);
  188. CGContextScaleCTM(context, 1.0, -1.0);
  189. CGRect rect = CGRectMake(0, 0, size.width, size.height);
  190. // ---
  191. if (tintStyle == UIImageTintedStyleOverAlpha)
  192. {
  193. [color setFill];
  194. CGContextFillRect(context, rect);
  195. }
  196. // draw alpha-mask
  197. CGContextSetBlendMode(context, kCGBlendModeNormal);
  198. CGContextDrawImage(context, rect, self.CGImage);
  199. if (tintStyle == UIImageTintedStyleKeepingAlpha)
  200. {
  201. CGContextSetBlendMode(context, kCGBlendModeSourceIn);
  202. [color setFill];
  203. CGContextFillRect(context, rect);
  204. }
  205. // ---
  206. CGImageRef bitmapContext = CGBitmapContextCreateImage(context);
  207. UIImage *coloredImage = [UIImage imageWithCGImage:bitmapContext scale:scale orientation:UIImageOrientationUp];
  208. CGImageRelease(bitmapContext);
  209. UIGraphicsEndImageContext();
  210. return coloredImage;
  211. }
  212. - (UIImage*)imageWithRoundedBounds
  213. {
  214. CGSize size = self.size;
  215. CGFloat radius = MIN(size.width, size.height) / 2.0;
  216. return [self imageWithCornerRadius:radius];
  217. }
  218. - (UIImage*)imageWithCornerRadius:(CGFloat)cornerRadius
  219. {
  220. return [self imageWithCornerInset:UICornerInsetMake(cornerRadius, cornerRadius, cornerRadius, cornerRadius)];
  221. }
  222. - (UIImage *)imageWithCornerInset:(UICornerInset)cornerInset
  223. {
  224. if (![self isValidCornerInset:cornerInset])
  225. return nil;
  226. CGFloat scale = self.scale;
  227. CGRect rect = CGRectMake(0.0f, 0.0f, scale*self.size.width, scale*self.size.height);
  228. cornerInset.topRight *= scale;
  229. cornerInset.topLeft *= scale;
  230. cornerInset.bottomLeft *= scale;
  231. cornerInset.bottomRight *= scale;
  232. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  233. CGContextRef context = CGBitmapContextCreate(NULL, rect.size.width, rect.size.height, 8, 0, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedLast);
  234. CGColorSpaceRelease(colorSpace);
  235. if (context == NULL)
  236. return nil;
  237. CGFloat minx = CGRectGetMinX(rect), midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect);
  238. CGFloat miny = CGRectGetMinY(rect), midy = CGRectGetMidY(rect), maxy = CGRectGetMaxY(rect);
  239. CGContextBeginPath(context);
  240. CGContextMoveToPoint(context, minx, midy);
  241. CGContextAddArcToPoint(context, minx, miny, midx, miny, cornerInset.bottomLeft);
  242. CGContextAddArcToPoint(context, maxx, miny, maxx, midy, cornerInset.bottomRight);
  243. CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, cornerInset.topRight);
  244. CGContextAddArcToPoint(context, minx, maxy, minx, midy, cornerInset.topLeft);
  245. CGContextClosePath(context);
  246. CGContextClip(context);
  247. CGContextDrawImage(context, rect, self.CGImage);
  248. CGImageRef bitmapImageRef = CGBitmapContextCreateImage(context);
  249. CGContextRelease(context);
  250. UIImage *newImage = [UIImage imageWithCGImage:bitmapImageRef scale:scale orientation:UIImageOrientationUp];
  251. CGImageRelease(bitmapImageRef);
  252. return newImage;
  253. }
  254. - (BOOL)isValidCornerInset:(UICornerInset)cornerInset
  255. {
  256. CGSize size = self.size;
  257. BOOL isValid = YES;
  258. if (cornerInset.topLeft + cornerInset.topRight > size.width)
  259. isValid = NO;
  260. else if (cornerInset.topRight + cornerInset.bottomRight > size.height)
  261. isValid = NO;
  262. else if (cornerInset.bottomRight + cornerInset.bottomLeft > size.width)
  263. isValid = NO;
  264. else if (cornerInset.bottomLeft + cornerInset.topLeft > size.height)
  265. isValid = NO;
  266. return isValid;
  267. }
  268. - (UIImage*)imageAddingImage:(UIImage*)image
  269. {
  270. CGSize size1 = self.size;
  271. CGSize size2 = image.size;
  272. CGPoint offset = CGPointMake(floorf((size1.width - size2.width)/2.0),
  273. floorf((size1.height - size2.height)/2.0));
  274. return [self imageAddingImage:image offset:offset];
  275. }
  276. - (UIImage*)imageAddingImage:(UIImage*)image offset:(CGPoint)offset
  277. {
  278. CGSize size = self.size;
  279. CGFloat scale = self.scale;
  280. size.width *= scale;
  281. size.height *= scale;
  282. UIGraphicsBeginImageContext(size);
  283. [self drawInRect:CGRectMake( 0, 0, size.width, size.height)];
  284. [image drawInRect:CGRectMake(scale * offset.x, scale * offset.y, image.size.width * scale, image.size.height * scale)];
  285. CGContextRef context = UIGraphicsGetCurrentContext();
  286. CGImageRef bitmapContext = CGBitmapContextCreateImage(context);
  287. UIImage *destImage = [UIImage imageWithCGImage:bitmapContext scale:image.scale orientation:UIImageOrientationUp];
  288. UIGraphicsEndImageContext();
  289. CGImageRelease(bitmapContext);
  290. return destImage;
  291. }
  292. #pragma mark Private Methods
  293. + (NSCache*)_cache
  294. {
  295. if (!_imageCache)
  296. _imageCache = [[NSCache alloc] init];
  297. return _imageCache;
  298. }
  299. + (UIImage*)_cachedImageWithDescriptors:(NSDictionary*)descriptors
  300. {
  301. return [[self _cache] objectForKey:[self _keyForImageWithDescriptors:descriptors]];
  302. }
  303. + (void)_cacheImage:(UIImage*)image withDescriptors:(NSDictionary*)descriptors
  304. {
  305. NSString *key = [self _keyForImageWithDescriptors:descriptors];
  306. [[self _cache] setObject:image forKey:key];
  307. }
  308. + (NSString*)_keyForImageWithDescriptors:(NSDictionary*)descriptors
  309. {
  310. NSMutableString *string = [NSMutableString string];
  311. NSString *imageName = [descriptors valueForKey:kUIImageName];
  312. [string appendFormat:@"<%@:%@>",kUIImageName,(imageName == nil)?@"":imageName];
  313. [string appendFormat:@"<%@:%@>",kUIImageSize, NSStringFromCGSize([[descriptors valueForKey:kUIImageSize] CGSizeValue])];
  314. [string appendFormat:@"<%@:%d>",kUIImageResizableImage,[[descriptors valueForKey:kUIImageResizableImage] boolValue]];
  315. [string appendFormat:@"<%@:",kUIImageColors];
  316. NSArray *colors = [descriptors valueForKey:kUIImageColors];
  317. for (UIColor *color in colors)
  318. [string appendFormat:@"%ld",(long)color.hash];
  319. [string appendFormat:@">"];
  320. [string appendFormat:@"<%@:%ld>",kUIImageTintColor,(long)[[descriptors valueForKey:kUIImageTintColor] hash]];
  321. [string appendFormat:@"<%@:%ld>",kUIImageTintStyle,(long)[[descriptors valueForKey:kUIImageTintStyle] integerValue]];
  322. [string appendFormat:@"<%@:%@>",kUIImageCornerInset,NSStringFromUICornerInset([[descriptors valueForKey:kUIImageCornerInset] UICornerInsetValue])];
  323. [string appendFormat:@"<%@:%ld>",kUIImageGradientDirection,(long)[[descriptors valueForKey:kUIImageGradientDirection] integerValue]];
  324. return [string md5];
  325. }
  326. + (UIImage*)_imageWithColor:(UIColor*)color size:(CGSize)size cornerInset:(UICornerInset)cornerInset saveInCache:(BOOL)save
  327. {
  328. NSDictionary *descriptors = @{kUIImageColors : @[color],
  329. kUIImageSize : [NSValue valueWithCGSize:size],
  330. kUIImageCornerInset : [NSValue valueWithUICornerInset:cornerInset]};
  331. UIImage *image = [self _cachedImageWithDescriptors:descriptors];
  332. if (image)
  333. return image;
  334. CGFloat scale = [[UIScreen mainScreen] scale];
  335. CGRect rect = CGRectMake(0.0f, 0.0f, scale*size.width, scale*size.height);
  336. cornerInset.topRight *= scale;
  337. cornerInset.topLeft *= scale;
  338. cornerInset.bottomLeft *= scale;
  339. cornerInset.bottomRight *= scale;
  340. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  341. CGContextRef context = CGBitmapContextCreate(NULL, rect.size.width, rect.size.height, 8, 0, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedLast);
  342. CGColorSpaceRelease(colorSpace);
  343. if (context == NULL)
  344. return nil;
  345. CGFloat minx = CGRectGetMinX(rect), midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect);
  346. CGFloat miny = CGRectGetMinY(rect), midy = CGRectGetMidY(rect), maxy = CGRectGetMaxY(rect);
  347. CGContextBeginPath(context);
  348. CGContextSetGrayFillColor(context, 1.0, 0.0); // <-- Alpha color in background
  349. CGContextAddRect(context, rect);
  350. CGContextClosePath(context);
  351. CGContextDrawPath(context, kCGPathFill);
  352. CGContextSetFillColorWithColor(context, [color CGColor]); // <-- Color to fill
  353. CGContextBeginPath(context);
  354. CGContextMoveToPoint(context, minx, midy);
  355. CGContextAddArcToPoint(context, minx, miny, midx, miny, cornerInset.bottomLeft);
  356. CGContextAddArcToPoint(context, maxx, miny, maxx, midy, cornerInset.bottomRight);
  357. CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, cornerInset.topRight);
  358. CGContextAddArcToPoint(context, minx, maxy, minx, midy, cornerInset.topLeft);
  359. CGContextClosePath(context);
  360. CGContextDrawPath(context, kCGPathFill);
  361. CGImageRef bitmapContext = CGBitmapContextCreateImage(context);
  362. CGContextRelease(context);
  363. UIImage *theImage = [UIImage imageWithCGImage:bitmapContext scale:scale orientation:UIImageOrientationUp];
  364. CGImageRelease(bitmapContext);
  365. if (save)
  366. [self _cacheImage:theImage withDescriptors:descriptors];
  367. return theImage;
  368. }
  369. + (UIImage*)imageWithGradient:(NSArray*)colors size:(CGSize)size direction:(UIImageGradientDirection)direction
  370. {
  371. NSDictionary *descriptors = @{kUIImageColors: colors,
  372. kUIImageSize: [NSValue valueWithCGSize:size],
  373. kUIImageGradientDirection: @(direction)};
  374. UIImage *image = [self _cachedImageWithDescriptors:descriptors];
  375. if (image)
  376. return image;
  377. CGRect rect = CGRectMake(0, 0, size.width, size.height);
  378. UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0);
  379. CGContextRef context = UIGraphicsGetCurrentContext();
  380. // Create Gradient
  381. NSMutableArray *cgColors = [NSMutableArray arrayWithCapacity:colors.count];
  382. for (UIColor *color in colors)
  383. [cgColors addObject:(id)color.CGColor];
  384. CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
  385. CGGradientRef gradient = CGGradientCreateWithColors(space, (__bridge CFArrayRef)cgColors, NULL);
  386. // Apply gradient
  387. CGPoint startPoint = CGPointZero;
  388. CGPoint endPoint = CGPointZero;
  389. if (direction == UIImageGradientDirectionVertical)
  390. endPoint = CGPointMake(0, rect.size.height);
  391. else if (direction == UIImageGradientDirectionHorizontal)
  392. endPoint = CGPointMake(rect.size.width, 0);
  393. CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
  394. image = UIGraphicsGetImageFromCurrentImageContext();
  395. // Clean memory & End context
  396. UIGraphicsEndImageContext();
  397. CGGradientRelease(gradient);
  398. CGColorSpaceRelease(space);
  399. [self _cacheImage:image withDescriptors:descriptors];
  400. return image;
  401. }
  402. + (UIImage*)resizableImageWithGradient:(NSArray*)colors size:(CGSize)size direction:(UIImageGradientDirection)direction
  403. {
  404. if ((size.width == 0.0f && direction == UIImageGradientDirectionHorizontal) ||
  405. (size.height == 0.0f && direction == UIImageGradientDirectionVertical) ||
  406. (size.height == 0.0f && size.width == 0.0f))
  407. return nil;
  408. NSDictionary *descriptors = @{kUIImageColors: colors,
  409. kUIImageSize: [NSValue valueWithCGSize:size],
  410. kUIImageGradientDirection: @(direction),
  411. kUIImageResizableImage: @YES};
  412. UIImage *image = [self _cachedImageWithDescriptors:descriptors];
  413. if (image)
  414. return image;
  415. CGSize imageSize = CGSizeMake(1.0f, 1.0f);
  416. UIEdgeInsets insets = UIEdgeInsetsZero;
  417. if (direction == UIImageGradientDirectionVertical)
  418. {
  419. imageSize.height = size.height;
  420. insets = UIEdgeInsetsMake(0.0f, 1.0f, 0.0f, 1.0f);
  421. }
  422. else if (direction == UIImageGradientDirectionHorizontal)
  423. {
  424. imageSize.width = size.width;
  425. insets = UIEdgeInsetsMake(1.0f, 0.0f, 1.0f, 0.0f);
  426. }
  427. return [[self imageWithGradient:colors size:imageSize direction:direction] resizableImageWithCapInsets:insets];
  428. }
  429. - (UIImage *)imageWithTintColor:(UIColor *)tintColor
  430. {
  431. return [self imageWithTintColor:tintColor blendMode:kCGBlendModeDestinationIn];
  432. }
  433. - (UIImage *)imageWithGradientTintColor:(UIColor *)tintColor
  434. {
  435. return [self imageWithTintColor:tintColor blendMode:kCGBlendModeOverlay];
  436. }
  437. - (UIImage *)imageWithTintColor:(UIColor *)tintColor blendMode:(CGBlendMode)blendMode
  438. {
  439. if (!tintColor) {
  440. return self;
  441. }
  442. //We want to keep alpha, set opaque to NO; Use 0.0f for scale to use the scale factor of the device’s main screen.
  443. UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
  444. [tintColor setFill];
  445. CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height);
  446. UIRectFill(bounds);
  447. //Draw the tinted image in context
  448. [self drawInRect:bounds blendMode:blendMode alpha:1.0f];
  449. if (blendMode != kCGBlendModeDestinationIn)
  450. {
  451. [self drawInRect:bounds blendMode:kCGBlendModeDestinationIn alpha:1.0f];
  452. }
  453. UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext();
  454. UIGraphicsEndImageContext();
  455. return tintedImage;
  456. }
  457. @end
  458. #pragma mark - Categories
  459. @implementation NSValue (UICornerInset)
  460. + (NSValue*)valueWithUICornerInset:(UICornerInset)cornerInset
  461. {
  462. CGRect rect = CGRectMake(cornerInset.topLeft, cornerInset.topRight, cornerInset.bottomLeft, cornerInset.bottomRight);
  463. return [NSValue valueWithCGRect:rect];
  464. // UICornerInset inset = cornerInset;
  465. // return [[NSValue alloc] initWithBytes:&inset objCType:@encode(struct __UICornerInset)];
  466. }
  467. - (UICornerInset)UICornerInsetValue
  468. {
  469. CGRect rect = [self CGRectValue];
  470. return UICornerInsetMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
  471. // UICornerInset cornerInset;
  472. // [self getValue:&cornerInset];
  473. // return cornerInset;
  474. }
  475. @end