|
@@ -45,8 +45,7 @@ |
|
@@ -45,8 +45,7 @@ |
45
|
|
45
|
|
46
|
if (count <= 1) {
|
46
|
if (count <= 1) {
|
47
|
animatedImage = [[UIImage alloc] initWithData:data];
|
47
|
animatedImage = [[UIImage alloc] initWithData:data];
|
48
|
- }
|
|
|
49
|
- else {
|
48
|
+ } else {
|
50
|
NSMutableArray *images = [NSMutableArray array];
|
49
|
NSMutableArray *images = [NSMutableArray array];
|
51
|
|
50
|
|
52
|
NSTimeInterval duration = 0.0f;
|
51
|
NSTimeInterval duration = 0.0f;
|
|
@@ -103,9 +102,7 @@ |
|
@@ -103,9 +102,7 @@ |
103
|
NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
|
102
|
NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
|
104
|
if (delayTimeUnclampedProp) {
|
103
|
if (delayTimeUnclampedProp) {
|
105
|
frameDuration = [delayTimeUnclampedProp floatValue];
|
104
|
frameDuration = [delayTimeUnclampedProp floatValue];
|
106
|
- }
|
|
|
107
|
- else {
|
|
|
108
|
-
|
105
|
+ } else {
|
109
|
NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime];
|
106
|
NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime];
|
110
|
if (delayTimeProp) {
|
107
|
if (delayTimeProp) {
|
111
|
frameDuration = [delayTimeProp floatValue];
|
108
|
frameDuration = [delayTimeProp floatValue];
|
|
@@ -147,11 +144,22 @@ |
|
@@ -147,11 +144,22 @@ |
147
|
}
|
144
|
}
|
148
|
|
145
|
|
149
|
NSMutableData *imageData = [NSMutableData data];
|
146
|
NSMutableData *imageData = [NSMutableData data];
|
|
|
147
|
+ NSUInteger frameCount = 0; // assume static images by default
|
150
|
CFStringRef imageUTType = [NSData sd_UTTypeFromSDImageFormat:format];
|
148
|
CFStringRef imageUTType = [NSData sd_UTTypeFromSDImageFormat:format];
|
151
|
- NSUInteger frameCount = 1;
|
|
|
152
|
- if (image.images) {
|
|
|
153
|
- frameCount = image.images.count;
|
149
|
+#if SD_MAC
|
|
|
150
|
+ NSBitmapImageRep *bitmapRep;
|
|
|
151
|
+ for (NSImageRep *imageRep in image.representations) {
|
|
|
152
|
+ if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {
|
|
|
153
|
+ bitmapRep = (NSBitmapImageRep *)imageRep;
|
|
|
154
|
+ break;
|
|
|
155
|
+ }
|
154
|
}
|
156
|
}
|
|
|
157
|
+ if (bitmapRep) {
|
|
|
158
|
+ frameCount = [[bitmapRep valueForProperty:NSImageFrameCount] unsignedIntegerValue];
|
|
|
159
|
+ }
|
|
|
160
|
+#else
|
|
|
161
|
+ frameCount = image.images.count;
|
|
|
162
|
+#endif
|
155
|
|
163
|
|
156
|
// Create an image destination. GIF does not support EXIF image orientation
|
164
|
// Create an image destination. GIF does not support EXIF image orientation
|
157
|
CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, frameCount, NULL);
|
165
|
CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, frameCount, NULL);
|
|
@@ -160,29 +168,30 @@ |
|
@@ -160,29 +168,30 @@ |
160
|
return nil;
|
168
|
return nil;
|
161
|
}
|
169
|
}
|
162
|
|
170
|
|
163
|
-#ifdef SD_MAC
|
|
|
164
|
- CGImageDestinationAddImage(imageDestination, image.CGImage, nil);
|
|
|
165
|
-#else
|
|
|
166
|
- if (!image.images) {
|
171
|
+ if (frameCount == 0) {
|
167
|
// for static single GIF images
|
172
|
// for static single GIF images
|
168
|
CGImageDestinationAddImage(imageDestination, image.CGImage, nil);
|
173
|
CGImageDestinationAddImage(imageDestination, image.CGImage, nil);
|
169
|
} else {
|
174
|
} else {
|
170
|
// for animated GIF images
|
175
|
// for animated GIF images
|
171
|
NSUInteger loopCount = image.sd_imageLoopCount;
|
176
|
NSUInteger loopCount = image.sd_imageLoopCount;
|
172
|
- NSTimeInterval totalDuration = image.duration;
|
|
|
173
|
- NSTimeInterval frameDuration = totalDuration / frameCount;
|
|
|
174
|
NSDictionary *gifProperties = @{(__bridge_transfer NSString *)kCGImagePropertyGIFDictionary: @{(__bridge_transfer NSString *)kCGImagePropertyGIFLoopCount : @(loopCount)}};
|
177
|
NSDictionary *gifProperties = @{(__bridge_transfer NSString *)kCGImagePropertyGIFDictionary: @{(__bridge_transfer NSString *)kCGImagePropertyGIFLoopCount : @(loopCount)}};
|
175
|
CGImageDestinationSetProperties(imageDestination, (__bridge CFDictionaryRef)gifProperties);
|
178
|
CGImageDestinationSetProperties(imageDestination, (__bridge CFDictionaryRef)gifProperties);
|
176
|
for (size_t i = 0; i < frameCount; i++) {
|
179
|
for (size_t i = 0; i < frameCount; i++) {
|
177
|
@autoreleasepool {
|
180
|
@autoreleasepool {
|
178
|
- NSDictionary *frameProperties = @{(__bridge_transfer NSString *)kCGImagePropertyGIFDictionary : @{(__bridge_transfer NSString *)kCGImagePropertyGIFUnclampedDelayTime : @(frameDuration)}};
|
181
|
+#if SD_MAC
|
|
|
182
|
+ // NSBitmapImageRep need to manually change frame. "Good taste" API
|
|
|
183
|
+ [bitmapRep setProperty:NSImageCurrentFrame withValue:@(i)];
|
|
|
184
|
+ float frameDuration = [[bitmapRep valueForProperty:NSImageCurrentFrameDuration] floatValue];
|
|
|
185
|
+ CGImageRef frameImageRef = bitmapRep.CGImage;
|
|
|
186
|
+#else
|
|
|
187
|
+ float frameDuration = image.duration / frameCount;
|
179
|
CGImageRef frameImageRef = image.images[i].CGImage;
|
188
|
CGImageRef frameImageRef = image.images[i].CGImage;
|
|
|
189
|
+#endif
|
|
|
190
|
+ NSDictionary *frameProperties = @{(__bridge_transfer NSString *)kCGImagePropertyGIFDictionary : @{(__bridge_transfer NSString *)kCGImagePropertyGIFUnclampedDelayTime : @(frameDuration)}};
|
180
|
CGImageDestinationAddImage(imageDestination, frameImageRef, (__bridge CFDictionaryRef)frameProperties);
|
191
|
CGImageDestinationAddImage(imageDestination, frameImageRef, (__bridge CFDictionaryRef)frameProperties);
|
181
|
}
|
192
|
}
|
182
|
}
|
193
|
}
|
183
|
}
|
194
|
}
|
184
|
-#endif
|
|
|
185
|
-
|
|
|
186
|
// Finalize the destination.
|
195
|
// Finalize the destination.
|
187
|
if (CGImageDestinationFinalize(imageDestination) == NO) {
|
196
|
if (CGImageDestinationFinalize(imageDestination) == NO) {
|
188
|
// Handle failure.
|
197
|
// Handle failure.
|