UIImage+Metadata.m 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. * This file is part of the SDWebImage package.
  3. * (c) Olivier Poitrey <rs@dailymotion.com>
  4. *
  5. * For the full copyright and license information, please view the LICENSE
  6. * file that was distributed with this source code.
  7. */
  8. #import "UIImage+Metadata.h"
  9. #import "NSImage+Compatibility.h"
  10. #import "objc/runtime.h"
  11. @implementation UIImage (Metadata)
  12. #if SD_UIKIT || SD_WATCH
  13. - (NSUInteger)sd_imageLoopCount {
  14. NSUInteger imageLoopCount = 0;
  15. NSNumber *value = objc_getAssociatedObject(self, @selector(sd_imageLoopCount));
  16. if ([value isKindOfClass:[NSNumber class]]) {
  17. imageLoopCount = value.unsignedIntegerValue;
  18. }
  19. return imageLoopCount;
  20. }
  21. - (void)setSd_imageLoopCount:(NSUInteger)sd_imageLoopCount {
  22. NSNumber *value = @(sd_imageLoopCount);
  23. objc_setAssociatedObject(self, @selector(sd_imageLoopCount), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  24. }
  25. - (BOOL)sd_isAnimated {
  26. return (self.images != nil);
  27. }
  28. #else
  29. - (NSUInteger)sd_imageLoopCount {
  30. NSUInteger imageLoopCount = 0;
  31. NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);
  32. NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil];
  33. NSBitmapImageRep *bitmapImageRep;
  34. if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {
  35. bitmapImageRep = (NSBitmapImageRep *)imageRep;
  36. }
  37. if (bitmapImageRep) {
  38. imageLoopCount = [[bitmapImageRep valueForProperty:NSImageLoopCount] unsignedIntegerValue];
  39. }
  40. return imageLoopCount;
  41. }
  42. - (void)setSd_imageLoopCount:(NSUInteger)sd_imageLoopCount {
  43. NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);
  44. NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil];
  45. NSBitmapImageRep *bitmapImageRep;
  46. if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {
  47. bitmapImageRep = (NSBitmapImageRep *)imageRep;
  48. }
  49. if (bitmapImageRep) {
  50. [bitmapImageRep setProperty:NSImageLoopCount withValue:@(sd_imageLoopCount)];
  51. }
  52. }
  53. - (BOOL)sd_isAnimated {
  54. BOOL isGIF = NO;
  55. NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);
  56. NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil];
  57. NSBitmapImageRep *bitmapImageRep;
  58. if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {
  59. bitmapImageRep = (NSBitmapImageRep *)imageRep;
  60. }
  61. if (bitmapImageRep) {
  62. NSUInteger frameCount = [[bitmapImageRep valueForProperty:NSImageFrameCount] unsignedIntegerValue];
  63. isGIF = frameCount > 1 ? YES : NO;
  64. }
  65. return isGIF;
  66. }
  67. #endif
  68. - (SDImageFormat)sd_imageFormat {
  69. SDImageFormat imageFormat = SDImageFormatUndefined;
  70. NSNumber *value = objc_getAssociatedObject(self, @selector(sd_imageFormat));
  71. if ([value isKindOfClass:[NSNumber class]]) {
  72. imageFormat = value.integerValue;
  73. return imageFormat;
  74. }
  75. // Check CGImage's UTType, may return nil for non-Image/IO based image
  76. if (@available(iOS 9.0, tvOS 9.0, macOS 10.11, watchOS 2.0, *)) {
  77. CFStringRef uttype = CGImageGetUTType(self.CGImage);
  78. imageFormat = [NSData sd_imageFormatFromUTType:uttype];
  79. }
  80. return imageFormat;
  81. }
  82. - (void)setSd_imageFormat:(SDImageFormat)sd_imageFormat {
  83. objc_setAssociatedObject(self, @selector(sd_imageFormat), @(sd_imageFormat), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  84. }
  85. - (void)setSd_isIncremental:(BOOL)sd_isIncremental {
  86. objc_setAssociatedObject(self, @selector(sd_isIncremental), @(sd_isIncremental), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  87. }
  88. - (BOOL)sd_isIncremental {
  89. NSNumber *value = objc_getAssociatedObject(self, @selector(sd_isIncremental));
  90. return value.boolValue;
  91. }
  92. @end