@@ -17,9 +17,9 @@ + (UIImage *)sd_animatedGIFWithData:(NSData *)data
17
17
{
18
18
return nil ;
19
19
}
20
-
20
+
21
21
CGImageSourceRef source = CGImageSourceCreateWithData ((__bridge CFDataRef)data, NULL );
22
-
22
+
23
23
size_t count = CGImageSourceGetCount (source);
24
24
25
25
UIImage *animatedImage;
@@ -38,8 +38,7 @@ + (UIImage *)sd_animatedGIFWithData:(NSData *)data
38
38
{
39
39
CGImageRef image = CGImageSourceCreateImageAtIndex (source, i, NULL );
40
40
41
- NSDictionary *frameProperties = CFBridgingRelease (CGImageSourceCopyPropertiesAtIndex (source, i, NULL ));
42
- duration += [[[frameProperties objectForKey: (NSString *)kCGImagePropertyGIFDictionary ] objectForKey: (NSString *)kCGImagePropertyGIFDelayTime ] doubleValue ];
41
+ duration += [self frameDurationAtIndex: i source: source];
43
42
44
43
[images addObject: [UIImage imageWithCGImage: image scale: [UIScreen mainScreen ].scale orientation: UIImageOrientationUp]];
45
44
@@ -59,45 +58,81 @@ + (UIImage *)sd_animatedGIFWithData:(NSData *)data
59
58
return animatedImage;
60
59
}
61
60
61
+ + (float )frameDurationAtIndex : (NSUInteger )index source : (CGImageSourceRef)source
62
+ {
63
+ float frameDuration = 0 .1f ;
64
+ CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex (source, index, nil );
65
+ NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties;
66
+ NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary ];
67
+
68
+ NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime ];
69
+ if (delayTimeUnclampedProp)
70
+ {
71
+ frameDuration = [delayTimeUnclampedProp floatValue ];
72
+ }
73
+ else
74
+ {
75
+
76
+ NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime ];
77
+ if (delayTimeProp)
78
+ {
79
+ frameDuration = [delayTimeProp floatValue ];
80
+ }
81
+ }
82
+
83
+ // Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
84
+ // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
85
+ // a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082>
86
+ // for more information.
87
+
88
+ if (frameDuration < 0 .011f )
89
+ {
90
+ frameDuration = 0 .100f ;
91
+ }
92
+
93
+ CFRelease (cfFrameProperties);
94
+ return frameDuration;
95
+ }
96
+
62
97
+ (UIImage *)sd_animatedGIFNamed : (NSString *)name
63
98
{
64
99
CGFloat scale = [UIScreen mainScreen ].scale ;
65
-
100
+
66
101
if (scale > 1 .0f )
67
102
{
68
103
NSString *retinaPath = [[NSBundle mainBundle ] pathForResource: [name stringByAppendingString: @" @2x" ] ofType: @" gif" ];
69
-
104
+
70
105
NSData *data = [NSData dataWithContentsOfFile: retinaPath];
71
-
106
+
72
107
if (data)
73
108
{
74
109
return [UIImage sd_animatedGIFWithData: data];
75
110
}
76
-
111
+
77
112
NSString *path = [[NSBundle mainBundle ] pathForResource: name ofType: @" gif" ];
78
-
113
+
79
114
data = [NSData dataWithContentsOfFile: path];
80
-
115
+
81
116
if (data)
82
117
{
83
118
return [UIImage sd_animatedGIFWithData: data];
84
119
}
85
-
120
+
86
121
return [UIImage imageNamed: name];
87
122
}
88
123
else
89
124
{
90
125
NSString *path = [[NSBundle mainBundle ] pathForResource: name ofType: @" gif" ];
91
-
126
+
92
127
NSData *data = [NSData dataWithContentsOfFile: path];
93
-
128
+
94
129
if (data)
95
130
{
96
131
return [UIImage sd_animatedGIFWithData: data];
97
132
}
98
-
133
+
99
134
return [UIImage imageNamed: name];
100
- }
135
+ }
101
136
}
102
137
103
138
- (UIImage *)sd_animatedImageByScalingAndCroppingToSize : (CGSize)size
@@ -106,40 +141,40 @@ - (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size
106
141
{
107
142
return self;
108
143
}
109
-
144
+
110
145
CGSize scaledSize = size;
111
- CGPoint thumbnailPoint = CGPointZero;
112
-
146
+ CGPoint thumbnailPoint = CGPointZero;
147
+
113
148
CGFloat widthFactor = size.width / self.size .width ;
114
149
CGFloat heightFactor = size.height / self.size .height ;
115
150
CGFloat scaleFactor = (widthFactor > heightFactor) ? widthFactor :heightFactor;
116
151
scaledSize.width = self.size .width * scaleFactor;
117
152
scaledSize.height = self.size .height * scaleFactor;
118
-
153
+
119
154
if (widthFactor > heightFactor)
120
155
{
121
- thumbnailPoint.y = (size.height - scaledSize.height ) * 0.5 ;
156
+ thumbnailPoint.y = (size.height - scaledSize.height ) * 0.5 ;
122
157
}
123
158
else if (widthFactor < heightFactor)
124
159
{
125
160
thumbnailPoint.x = (size.width - scaledSize.width ) * 0.5 ;
126
161
}
127
-
162
+
128
163
NSMutableArray *scaledImages = [NSMutableArray array ];
129
-
130
- UIGraphicsBeginImageContextWithOptions (size, NO , 0.0 );
131
-
164
+
165
+ UIGraphicsBeginImageContextWithOptions (size, NO , 0.0 );
166
+
132
167
for (UIImage *image in self.images )
133
168
{
134
169
[image drawInRect: CGRectMake (thumbnailPoint.x, thumbnailPoint.y, scaledSize.width, scaledSize.height)];
135
170
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext ();
136
-
171
+
137
172
[scaledImages addObject: newImage];
138
173
}
139
-
174
+
140
175
UIGraphicsEndImageContext ();
141
-
142
- return [UIImage animatedImageWithImages: scaledImages duration: self .duration];
176
+
177
+ return [UIImage animatedImageWithImages: scaledImages duration: self .duration];
143
178
}
144
179
145
180
@end
0 commit comments