Merge pull request #2390 from dreampiggy/feature_image_format
Keep the information about image's original compressed format, for API which only contains image but not image data to process extra logic
This commit is contained in:
commit
68c58992d7
|
@ -32,11 +32,19 @@ typedef NS_ENUM(NSInteger, SDImageFormat) {
|
|||
+ (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data;
|
||||
|
||||
/**
|
||||
Convert SDImageFormat to UTType
|
||||
|
||||
@param format Format as SDImageFormat
|
||||
@return The UTType as CFStringRef
|
||||
* Convert SDImageFormat to UTType
|
||||
*
|
||||
* @param format Format as SDImageFormat
|
||||
* @return The UTType as CFStringRef
|
||||
*/
|
||||
+ (nonnull CFStringRef)sd_UTTypeFromSDImageFormat:(SDImageFormat)format;
|
||||
|
||||
/**
|
||||
* Convert UTTyppe to SDImageFormat
|
||||
*
|
||||
* @param uttype The UTType as CFStringRef
|
||||
* @return The Format as SDImageFormat
|
||||
*/
|
||||
+ (SDImageFormat)sd_imageFormatFromUTType:(nonnull CFStringRef)uttype;
|
||||
|
||||
@end
|
||||
|
|
|
@ -95,4 +95,27 @@
|
|||
return UTType;
|
||||
}
|
||||
|
||||
+ (SDImageFormat)sd_imageFormatFromUTType:(CFStringRef)uttype {
|
||||
if (!uttype) {
|
||||
return SDImageFormatUndefined;
|
||||
}
|
||||
SDImageFormat imageFormat;
|
||||
if (CFStringCompare(uttype, kUTTypeJPEG, 0) == kCFCompareEqualTo) {
|
||||
imageFormat = SDImageFormatJPEG;
|
||||
} else if (CFStringCompare(uttype, kUTTypePNG, 0) == kCFCompareEqualTo) {
|
||||
imageFormat = SDImageFormatPNG;
|
||||
} else if (CFStringCompare(uttype, kUTTypeGIF, 0) == kCFCompareEqualTo) {
|
||||
imageFormat = SDImageFormatGIF;
|
||||
} else if (CFStringCompare(uttype, kUTTypeTIFF, 0) == kCFCompareEqualTo) {
|
||||
imageFormat = SDImageFormatTIFF;
|
||||
} else if (CFStringCompare(uttype, kSDUTTypeWebP, 0) == kCFCompareEqualTo) {
|
||||
imageFormat = SDImageFormatWebP;
|
||||
} else if (CFStringCompare(uttype, kSDUTTypeHEIC, 0) == kCFCompareEqualTo) {
|
||||
imageFormat = SDImageFormatHEIC;
|
||||
} else {
|
||||
imageFormat = SDImageFormatUndefined;
|
||||
}
|
||||
return imageFormat;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#ifdef SD_WEBP
|
||||
#import "SDWebImageWebPCoder.h"
|
||||
#endif
|
||||
#import "UIImage+MultiFormat.h"
|
||||
|
||||
#define LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
|
||||
#define UNLOCK(lock) dispatch_semaphore_signal(lock);
|
||||
|
@ -121,7 +122,9 @@
|
|||
UNLOCK(self.codersLock);
|
||||
for (id<SDWebImageCoder> coder in coders.reverseObjectEnumerator) {
|
||||
if ([coder canDecodeFromData:*data]) {
|
||||
return [coder decompressedImageWithImage:image data:data options:optionsDict];
|
||||
UIImage *decompressedImage = [coder decompressedImageWithImage:image data:data options:optionsDict];
|
||||
decompressedImage.sd_imageFormat = image.sd_imageFormat;
|
||||
return decompressedImage;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
|
|
|
@ -35,6 +35,7 @@ inline UIImage *SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullabl
|
|||
UIImage *animatedImage = [UIImage animatedImageWithImages:scaledImages duration:image.duration];
|
||||
if (animatedImage) {
|
||||
animatedImage.sd_imageLoopCount = image.sd_imageLoopCount;
|
||||
animatedImage.sd_imageFormat = image.sd_imageFormat;
|
||||
}
|
||||
return animatedImage;
|
||||
} else {
|
||||
|
@ -57,6 +58,7 @@ inline UIImage *SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullabl
|
|||
}
|
||||
|
||||
UIImage *scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation];
|
||||
scaledImage.sd_imageFormat = image.sd_imageFormat;
|
||||
image = scaledImage;
|
||||
}
|
||||
return image;
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
|
||||
animatedImage = [SDWebImageCoderHelper animatedImageWithFrames:frames];
|
||||
animatedImage.sd_imageLoopCount = loopCount;
|
||||
animatedImage.sd_imageFormat = SDImageFormatGIF;
|
||||
}
|
||||
|
||||
CFRelease(source);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#import "NSImage+WebCache.h"
|
||||
#import <ImageIO/ImageIO.h>
|
||||
#import "NSData+ImageContentType.h"
|
||||
#import "UIImage+MultiFormat.h"
|
||||
|
||||
#if SD_UIKIT || SD_WATCH
|
||||
static const size_t kBytesPerPixel = 4;
|
||||
|
@ -97,6 +98,7 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over
|
|||
}
|
||||
|
||||
UIImage *image = [[UIImage alloc] initWithData:data];
|
||||
image.sd_imageFormat = [NSData sd_imageFormatForImageData:data];
|
||||
|
||||
return image;
|
||||
}
|
||||
|
@ -146,6 +148,7 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over
|
|||
image = [[UIImage alloc] initWithCGImage:partialImageRef size:NSZeroSize];
|
||||
#endif
|
||||
CGImageRelease(partialImageRef);
|
||||
image.sd_imageFormat = [NSData sd_imageFormatForImageData:data];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -106,6 +106,7 @@
|
|||
}
|
||||
WebPDemuxDelete(demuxer);
|
||||
CGContextRelease(canvas);
|
||||
staticImage.sd_imageFormat = SDImageFormatWebP;
|
||||
return staticImage;
|
||||
}
|
||||
|
||||
|
@ -145,6 +146,7 @@
|
|||
|
||||
UIImage *animatedImage = [SDWebImageCoderHelper animatedImageWithFrames:frames];
|
||||
animatedImage.sd_imageLoopCount = loopCount;
|
||||
animatedImage.sd_imageFormat = SDImageFormatWebP;
|
||||
|
||||
return animatedImage;
|
||||
}
|
||||
|
@ -215,6 +217,7 @@
|
|||
#else
|
||||
image = [[UIImage alloc] initWithCGImage:newImageRef size:NSZeroSize];
|
||||
#endif
|
||||
image.sd_imageFormat = SDImageFormatWebP;
|
||||
CGImageRelease(newImageRef);
|
||||
CGContextRelease(canvas);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* UIKit:
|
||||
* For static image format, this value is always 0.
|
||||
* 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.
|
||||
* @note 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
|
||||
|
@ -23,6 +23,13 @@
|
|||
*/
|
||||
@property (nonatomic, assign) NSUInteger sd_imageLoopCount;
|
||||
|
||||
/**
|
||||
* The image format represent the original compressed image data format.
|
||||
* If you don't manually specify a format, this information is retrieve from CGImage using `CGImageGetUTType`, which may return nil for non-CG based image. At this time it will return `SDImageFormatUndefined` as default value.
|
||||
* @note 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.
|
||||
*/
|
||||
@property (nonatomic, assign) SDImageFormat sd_imageFormat;
|
||||
|
||||
+ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data;
|
||||
- (nullable NSData *)sd_imageData;
|
||||
- (nullable NSData *)sd_imageDataAsFormat:(SDImageFormat)imageFormat;
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
*/
|
||||
|
||||
#import "UIImage+MultiFormat.h"
|
||||
|
||||
#import "objc/runtime.h"
|
||||
#import "NSImage+WebCache.h"
|
||||
#import "SDWebImageCodersManager.h"
|
||||
#import "objc/runtime.h"
|
||||
|
||||
@implementation UIImage (MultiFormat)
|
||||
|
||||
|
@ -53,6 +53,28 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
- (SDImageFormat)sd_imageFormat {
|
||||
SDImageFormat imageFormat = SDImageFormatUndefined;
|
||||
NSNumber *value = objc_getAssociatedObject(self, @selector(sd_imageFormat));
|
||||
if ([value isKindOfClass:[NSNumber class]]) {
|
||||
imageFormat = value.integerValue;
|
||||
return imageFormat;
|
||||
}
|
||||
// Check CGImage's UTType, may return nil for non-Image/IO based image
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability"
|
||||
if (&CGImageGetUTType != NULL) {
|
||||
CFStringRef uttype = CGImageGetUTType(self.CGImage);
|
||||
imageFormat = [NSData sd_imageFormatFromUTType:uttype];
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
return imageFormat;
|
||||
}
|
||||
|
||||
- (void)setSd_imageFormat:(SDImageFormat)sd_imageFormat {
|
||||
objc_setAssociatedObject(self, @selector(sd_imageFormat), @(sd_imageFormat), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
+ (nullable UIImage *)sd_imageWithData:(nullable NSData *)data {
|
||||
return [[SDWebImageCodersManager sharedInstance] decodedImageWithData:data];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue