UIImage+ColoredImage.m 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // _____ _
  2. // |_ _| |_ _ _ ___ ___ _ __ __ _
  3. // | | | ' \| '_/ -_) -_) ' \/ _` |_
  4. // |_| |_||_|_| \___\___|_|_|_\__,_(_)
  5. //
  6. // Threema iOS Client
  7. // Copyright (c) 2014-2020 Threema GmbH
  8. //
  9. // This program is free software: you can redistribute it and/or modify
  10. // it under the terms of the GNU Affero General Public License, version 3,
  11. // as published by the Free Software Foundation.
  12. //
  13. // This program is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. // GNU Affero General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Affero General Public License
  19. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. #import "UIImage+ColoredImage.h"
  21. @implementation UIImage (ColoredImage)
  22. static CGFloat scale = -1.0;
  23. static NSCache *imageCache = nil;
  24. + (UIImage *) imageNamed:(NSString *)name inColor: (UIColor *) color
  25. {
  26. NSString *cacheKey = [NSString stringWithFormat:@"%@/%@", name, color];
  27. // Check cache first
  28. UIImage *image;
  29. if (imageCache != nil) {
  30. image = [imageCache objectForKey:cacheKey];
  31. if (image != nil) {
  32. return image;
  33. }
  34. }
  35. image = [[UIImage imageNamed:name] imageWithTint: color];
  36. // Put in cache
  37. if (imageCache == nil) {
  38. imageCache = [[NSCache alloc] init];
  39. imageCache.name = @"ColoredImage cache";
  40. }
  41. [imageCache setObject:image forKey:cacheKey];
  42. return image;
  43. }
  44. - (UIImage *) imageWithTint:(UIColor *)tintColor {
  45. if (@available(iOS 13.0, *)) {
  46. return [self imageWithTintColor:tintColor];
  47. }
  48. return [self drawImageWithTintColor:tintColor];
  49. }
  50. // Only use this function before iOS 13 or for non icon images
  51. - (UIImage *)drawImageWithTintColor:(UIColor *)tintColor {
  52. if (scale<0.0) {
  53. UIScreen *screen = [UIScreen mainScreen];
  54. scale = [screen scale];
  55. }
  56. CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
  57. UIGraphicsBeginImageContextWithOptions(rect.size, NO, scale);
  58. CGContextRef context = UIGraphicsGetCurrentContext();
  59. CGContextTranslateCTM(context, 0, self.size.height);
  60. CGContextScaleCTM(context, 1.0, -1.0);
  61. CGContextSetBlendMode(context, kCGBlendModeNormal);
  62. CGContextDrawImage(context, rect, self.CGImage);
  63. CGContextSetBlendMode(context, kCGBlendModeSourceIn);
  64. [tintColor setFill];
  65. CGContextFillRect(context, rect);
  66. UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext();
  67. UIGraphicsEndImageContext();
  68. return coloredImage;
  69. }
  70. - (UIImage *) invertedImage {
  71. CIImage *img = [CIImage imageWithCGImage:self.CGImage];
  72. CIFilter *filter = [CIFilter filterWithName:@"CIColorInvert"];
  73. [filter setDefaults];
  74. [filter setValue:img forKey:@"inputImage"];
  75. CIContext *context = [[CIContext alloc] init];
  76. CGImageRef ref = [context createCGImage:filter.outputImage fromRect:filter.outputImage.extent];
  77. return [UIImage imageWithCGImage:ref];
  78. }
  79. @end