Added `sd_imageFrameCount` convenient API for UIAinmatedImage/NSBitmapImageRep
Fix one issue when input UIAnimatedImage contains only 1 image
This commit is contained in:
parent
fd326e3d51
commit
4ae33983e0
|
@ -135,7 +135,6 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over
|
|||
avgDuration = 0.1; // if it's a animated image but no duration, set it to default 100ms (this do not have that 10ms limit like GIF or WebP to allow custom coder provide the limit)
|
||||
}
|
||||
|
||||
__block NSUInteger index = 0;
|
||||
__block NSUInteger repeatCount = 1;
|
||||
__block UIImage *previousImage = animatedImages.firstObject;
|
||||
[animatedImages enumerateObjectsUsingBlock:^(UIImage * _Nonnull image, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
|
@ -149,15 +148,12 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over
|
|||
SDImageFrame *frame = [SDImageFrame frameWithImage:previousImage duration:avgDuration * repeatCount];
|
||||
[frames addObject:frame];
|
||||
repeatCount = 1;
|
||||
index++;
|
||||
}
|
||||
previousImage = image;
|
||||
// last one
|
||||
if (idx == frameCount - 1) {
|
||||
SDImageFrame *frame = [SDImageFrame frameWithImage:previousImage duration:avgDuration * repeatCount];
|
||||
[frames addObject:frame];
|
||||
}
|
||||
}];
|
||||
// last one
|
||||
SDImageFrame *frame = [SDImageFrame frameWithImage:previousImage duration:avgDuration * repeatCount];
|
||||
[frames addObject:frame];
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
@ -20,12 +20,23 @@
|
|||
* For animated image format, 0 means infinite looping.
|
||||
* Note that because of the limitations of categories this property can get out of sync if you create another instance with CGImage or other methods.
|
||||
* AppKit:
|
||||
* NSImage currently only support animated via GIF imageRep unlike UIImage.
|
||||
* The getter of this property will get the loop count from GIF imageRep
|
||||
* The setter of this property will set the loop count from GIF imageRep
|
||||
* NSImage currently only support animated via `NSBitmapImageRep`(GIF) or `SDAnimatedImageRep`(APNG/GIF/WebP) unlike UIImage.
|
||||
* The getter of this property will get the loop count from animated imageRep
|
||||
* The setter of this property will set the loop count from animated imageRep
|
||||
*/
|
||||
@property (nonatomic, assign) NSUInteger sd_imageLoopCount;
|
||||
|
||||
/**
|
||||
* UIKit:
|
||||
* Returns the `images`'s count by unapply the patch for the different frame durations. Which matches the real visible frame count when displaying on UIImageView.
|
||||
* See more in `SDImageCoderHelper.animatedImageWithFrames`.
|
||||
* Returns 1 for static image.
|
||||
* AppKit:
|
||||
* Returns the underlaying `NSBitmapImageRep` or `SDAnimatedImageRep` frame count.
|
||||
* Returns 1 for static image.
|
||||
*/
|
||||
@property (nonatomic, assign, readonly) NSUInteger sd_imageFrameCount;
|
||||
|
||||
/**
|
||||
* UIKit:
|
||||
* Check the `images` array property.
|
||||
|
|
|
@ -29,6 +29,27 @@
|
|||
objc_setAssociatedObject(self, @selector(sd_imageLoopCount), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (NSUInteger)sd_imageFrameCount {
|
||||
NSArray<UIImage *> *animatedImages = self.images;
|
||||
if (!animatedImages || animatedImages.count <= 1) {
|
||||
return 1;
|
||||
}
|
||||
__block NSUInteger frameCount = 1;
|
||||
__block UIImage *previousImage = animatedImages.firstObject;
|
||||
[animatedImages enumerateObjectsUsingBlock:^(UIImage * _Nonnull image, NSUInteger idx, BOOL * _Nonnull stop) {
|
||||
// ignore first
|
||||
if (idx == 0) {
|
||||
return;
|
||||
}
|
||||
if (![image isEqual:previousImage]) {
|
||||
frameCount++;
|
||||
}
|
||||
previousImage = image;
|
||||
}];
|
||||
|
||||
return frameCount;
|
||||
}
|
||||
|
||||
- (BOOL)sd_isAnimated {
|
||||
return (self.images != nil);
|
||||
}
|
||||
|
@ -87,6 +108,19 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (NSUInteger)sd_imageFrameCount {
|
||||
NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);
|
||||
NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil];
|
||||
NSBitmapImageRep *bitmapImageRep;
|
||||
if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {
|
||||
bitmapImageRep = (NSBitmapImageRep *)imageRep;
|
||||
}
|
||||
if (bitmapImageRep) {
|
||||
return [[bitmapImageRep valueForProperty:NSImageFrameCount] unsignedIntegerValue];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (BOOL)sd_isAnimated {
|
||||
BOOL isAnimated = NO;
|
||||
NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);
|
||||
|
|
|
@ -770,7 +770,10 @@ static BOOL _isCalled;
|
|||
[[SDImageCodersManager sharedManager] addCoder:[SDImageAWebPCoder sharedCoder]];
|
||||
UIImage *image = [UIImage sd_imageWithData:[NSData dataWithContentsOfFile:[self testMemotyCostImagePath]]];
|
||||
NSUInteger cost = [image sd_memoryCost];
|
||||
#if SD_UIKIT
|
||||
expect(image.images.count).equal(5333);
|
||||
#endif
|
||||
expect(image.sd_imageFrameCount).equal(16);
|
||||
expect(image.scale).equal(1);
|
||||
expect(cost).equal(16 * image.size.width * image.size.height * 4);
|
||||
[[SDImageCodersManager sharedManager] removeCoder:[SDImageAWebPCoder sharedCoder]];
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
image = [UIImage sd_imageWithGIFData:data];
|
||||
expect(image).notTo.beNil();
|
||||
expect(image.sd_isAnimated).beTruthy();
|
||||
expect(image.sd_imageFrameCount).equal(5);
|
||||
}
|
||||
|
||||
#pragma mark - Helper
|
||||
|
|
|
@ -435,7 +435,7 @@ withLocalImageURL:(NSURL *)imageUrl
|
|||
}
|
||||
}
|
||||
|
||||
- (NSArray *)thumbnailImagesFromImageSource:(CGImageSourceRef)source API_AVAILABLE(ios(11.0), tvos(11.0), macos(13.0)) {
|
||||
- (NSArray *)thumbnailImagesFromImageSource:(CGImageSourceRef)source API_AVAILABLE(ios(11.0), tvos(11.0), macos(10.13)) {
|
||||
NSDictionary *properties = (__bridge_transfer NSDictionary *)CGImageSourceCopyProperties(source, nil);
|
||||
NSDictionary *fileProperties = properties[(__bridge NSString *)kCGImagePropertyFileContentsDictionary];
|
||||
NSArray *imagesProperties = fileProperties[(__bridge NSString *)kCGImagePropertyImages];
|
||||
|
|
Loading…
Reference in New Issue