Fix the scale factor issue on macOS using helper methods to match the behavior of UIKit. Also remove the unused API on NSImage category
This commit is contained in:
parent
1a3fb834a0
commit
cbf8581696
|
@ -8,16 +8,50 @@
|
|||
|
||||
#import "SDWebImageCompat.h"
|
||||
|
||||
// This category is provided to easily write cross-platform code. For common usage, see `UIImage+WebCache`.
|
||||
// This category is provided to easily write cross-platform(AppKit/UIKit) code. For common usage, see `UIImage+WebCache`.
|
||||
|
||||
#if SD_MAC
|
||||
|
||||
@interface NSImage (Additions)
|
||||
|
||||
/**
|
||||
The underlying Core Graphics image object. This will actually `CGImageForProposedRect` with the image size.
|
||||
*/
|
||||
@property (nonatomic, readonly, nullable) CGImageRef CGImage;
|
||||
@property (nonatomic, readonly, nullable) NSArray<NSImage *> *images;
|
||||
/**
|
||||
The scale factor of the image. This wil actually use image size, and its `CGImage`'s pixel size to calculate the scale factor. Should be greater than or equal to 1.0.
|
||||
*/
|
||||
@property (nonatomic, readonly) CGFloat scale;
|
||||
@property (nonatomic, readonly, nullable) NSBitmapImageRep *bitmapImageRep;
|
||||
|
||||
// These are convenience methods to make AppKit's `NSImage` match UIKit's `UIImage` behavior. The scale factor should be greater than or equal to 1.0.
|
||||
|
||||
/**
|
||||
Returns an image object with the scale factor. The representation is created from the Core Graphics image object.
|
||||
@note The difference between this and `initWithCGImage:size` is that `initWithCGImage:size` will create a `NSCGImageSnapshotRep` but not `NSBitmapImageRep` instance. And it will always `backingScaleFactor` as scale factor.
|
||||
|
||||
@param cgImage A Core Graphics image object
|
||||
@param scale The image scale factor
|
||||
@return The image object
|
||||
*/
|
||||
- (nonnull instancetype)initWithCGImage:(nonnull CGImageRef)cgImage scale:(CGFloat)scale;
|
||||
|
||||
/**
|
||||
Returns an image object with the scale factor. The representation is created from the image data.
|
||||
@note The difference between these this and `initWithData:` is that `initWithData:` will always `backingScaleFactor` as scale factor.
|
||||
|
||||
@param data The image data
|
||||
@param scale The image scale factor
|
||||
@return The image object
|
||||
*/
|
||||
- (nullable instancetype)initWithData:(nonnull NSData *)data scale:(CGFloat)scale;
|
||||
|
||||
@end
|
||||
|
||||
@interface NSBitmapImageRep (Additions)
|
||||
|
||||
// These method's function is the same as `NSImage`'s function. For `NSBitmapImageRep`.
|
||||
- (nonnull instancetype)initWithCGImage:(nonnull CGImageRef)cgImage scale:(CGFloat)scale;
|
||||
- (nullable instancetype)initWithData:(nonnull NSData *)data scale:(CGFloat)scale;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -18,28 +18,72 @@
|
|||
return cgImage;
|
||||
}
|
||||
|
||||
- (NSArray<NSImage *> *)images {
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (CGFloat)scale {
|
||||
CGFloat scale = 1;
|
||||
CGFloat width = self.size.width;
|
||||
if (width > 0) {
|
||||
// Use CGImage to get pixel width, NSImageRep.pixelsWide always double on Retina screen
|
||||
// Use CGImage to get pixel width, NSImageRep.pixelsWide may be double on Retina screen
|
||||
NSUInteger pixelWidth = CGImageGetWidth(self.CGImage);
|
||||
scale = pixelWidth / width;
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
|
||||
- (NSBitmapImageRep *)bitmapImageRep {
|
||||
NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);
|
||||
NSImageRep *imageRep = [self bestRepresentationForRect:imageRect context:nil hints:nil];
|
||||
if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {
|
||||
return (NSBitmapImageRep *)imageRep;
|
||||
- (instancetype)initWithCGImage:(CGImageRef)cgImage scale:(CGFloat)scale {
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
return nil;
|
||||
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage scale:scale];
|
||||
NSSize size = NSMakeSize(imageRep.pixelsWide / scale, imageRep.pixelsHigh / scale);
|
||||
self = [self initWithSize:size];
|
||||
if (self) {
|
||||
[self addRepresentation:imageRep];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithData:(NSData *)data scale:(CGFloat)scale {
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithData:data scale:scale];
|
||||
if (!imageRep) {
|
||||
return nil;
|
||||
}
|
||||
NSSize size = NSMakeSize(imageRep.pixelsWide / scale, imageRep.pixelsHigh / scale);
|
||||
self = [self initWithSize:size];
|
||||
if (self) {
|
||||
[self addRepresentation:imageRep];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSBitmapImageRep (Additions)
|
||||
|
||||
- (instancetype)initWithCGImage:(CGImageRef)cgImage scale:(CGFloat)scale {
|
||||
self = [self initWithCGImage:cgImage];
|
||||
if (self) {
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
NSSize size = NSMakeSize(self.pixelsWide / scale, self.pixelsHigh / scale);
|
||||
self.size = size;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithData:(NSData *)data scale:(CGFloat)scale {
|
||||
self = [self initWithData:data];
|
||||
if (self) {
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
NSSize size = NSMakeSize(self.pixelsWide / scale, self.pixelsHigh / scale);
|
||||
self.size = size;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -310,7 +310,7 @@ static NSArray *SDBundlePreferredScales() {
|
|||
return nil;
|
||||
}
|
||||
#if SD_MAC
|
||||
self = [super initWithCGImage:image.CGImage size:NSZeroSize];
|
||||
self = [super initWithCGImage:image.CGImage scale:scale];
|
||||
#else
|
||||
self = [super initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation];
|
||||
#endif
|
||||
|
@ -353,7 +353,10 @@ static NSArray *SDBundlePreferredScales() {
|
|||
NSNumber *scale = [aDecoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(scale))];
|
||||
NSData *animatedImageData = [aDecoder decodeObjectOfClass:[NSData class] forKey:NSStringFromSelector(@selector(animatedImageData))];
|
||||
if (animatedImageData) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
|
||||
return [self initWithData:animatedImageData scale:scale.doubleValue];
|
||||
#pragma clang diagnostic pop
|
||||
} else {
|
||||
return [super initWithCoder:aDecoder];
|
||||
}
|
||||
|
|
|
@ -82,10 +82,19 @@ const CFStringRef kCGImagePropertyAPNGUnclampedDelayTime = (__bridge CFStringRef
|
|||
if (!data) {
|
||||
return nil;
|
||||
}
|
||||
CGFloat scale = 1;
|
||||
if ([options valueForKey:SDWebImageCoderDecodeScaleFactor]) {
|
||||
scale = [[options valueForKey:SDWebImageCoderDecodeScaleFactor] doubleValue];
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if SD_MAC
|
||||
SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:data];
|
||||
NSImage *animatedImage = [[NSImage alloc] initWithSize:imageRep.size];
|
||||
NSSize size = NSMakeSize(imageRep.pixelsWide / scale, imageRep.pixelsHigh / scale);
|
||||
imageRep.size = size;
|
||||
NSImage *animatedImage = [[NSImage alloc] initWithSize:size];
|
||||
[animatedImage addRepresentation:imageRep];
|
||||
return animatedImage;
|
||||
#else
|
||||
|
@ -95,13 +104,6 @@ const CFStringRef kCGImagePropertyAPNGUnclampedDelayTime = (__bridge CFStringRef
|
|||
return nil;
|
||||
}
|
||||
size_t count = CGImageSourceGetCount(source);
|
||||
CGFloat scale = 1;
|
||||
if ([options valueForKey:SDWebImageCoderDecodeScaleFactor]) {
|
||||
scale = [[options valueForKey:SDWebImageCoderDecodeScaleFactor] doubleValue];
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
}
|
||||
UIImage *animatedImage;
|
||||
|
||||
if (count <= 1) {
|
||||
|
@ -277,10 +279,17 @@ const CFStringRef kCGImagePropertyAPNGUnclampedDelayTime = (__bridge CFStringRef
|
|||
CGImageRef partialImageRef = CGImageSourceCreateImageAtIndex(_imageSource, 0, NULL);
|
||||
|
||||
if (partialImageRef) {
|
||||
CGFloat scale = 1;
|
||||
if ([options valueForKey:SDWebImageCoderDecodeScaleFactor]) {
|
||||
scale = [[options valueForKey:SDWebImageCoderDecodeScaleFactor] doubleValue];
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
}
|
||||
#if SD_UIKIT || SD_WATCH
|
||||
image = [[UIImage alloc] initWithCGImage:partialImageRef];
|
||||
image = [[UIImage alloc] initWithCGImage:partialImageRef scale:scale orientation:UIImageOrientationUp];
|
||||
#elif SD_MAC
|
||||
image = [[UIImage alloc] initWithCGImage:partialImageRef size:NSZeroSize];
|
||||
image = [[UIImage alloc] initWithCGImage:partialImageRef scale:scale];
|
||||
#endif
|
||||
CGImageRelease(partialImageRef);
|
||||
}
|
||||
|
@ -375,7 +384,7 @@ const CFStringRef kCGImagePropertyAPNGUnclampedDelayTime = (__bridge CFStringRef
|
|||
CGImageRelease(imageRef);
|
||||
}
|
||||
#if SD_MAC
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:newImageRef size:NSZeroSize];
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:newImageRef scale:1];
|
||||
#else
|
||||
UIImage *image = [UIImage imageWithCGImage:newImageRef];
|
||||
#endif
|
||||
|
|
|
@ -103,8 +103,14 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over
|
|||
return nil;
|
||||
}
|
||||
CFRelease(imageDestination);
|
||||
CGFloat scale = frames.firstObject.image.scale;
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:imageData];
|
||||
animatedImage = [[NSImage alloc] initWithSize:imageRep.size];
|
||||
NSSize size = NSMakeSize(imageRep.pixelsWide / scale, imageRep.pixelsHigh / scale);
|
||||
imageRep.size = size;
|
||||
animatedImage = [[NSImage alloc] initWithSize:size];
|
||||
[animatedImage addRepresentation:imageRep];
|
||||
#endif
|
||||
|
||||
|
@ -157,27 +163,27 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over
|
|||
|
||||
#else
|
||||
|
||||
NSBitmapImageRep *bitmapRep;
|
||||
for (NSImageRep *imageRep in animatedImage.representations) {
|
||||
if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {
|
||||
bitmapRep = (NSBitmapImageRep *)imageRep;
|
||||
break;
|
||||
}
|
||||
NSRect imageRect = NSMakeRect(0, 0, animatedImage.size.width, animatedImage.size.height);
|
||||
NSImageRep *imageRep = [animatedImage bestRepresentationForRect:imageRect context:nil hints:nil];
|
||||
NSBitmapImageRep *bitmapImageRep;
|
||||
if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {
|
||||
bitmapImageRep = (NSBitmapImageRep *)imageRep;
|
||||
}
|
||||
if (bitmapRep) {
|
||||
frameCount = [[bitmapRep valueForProperty:NSImageFrameCount] unsignedIntegerValue];
|
||||
if (!bitmapImageRep) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
frameCount = [[bitmapImageRep valueForProperty:NSImageFrameCount] unsignedIntegerValue];
|
||||
if (frameCount == 0) {
|
||||
return nil;
|
||||
}
|
||||
CGFloat scale = animatedImage.scale;
|
||||
|
||||
for (size_t i = 0; i < frameCount; i++) {
|
||||
@autoreleasepool {
|
||||
// NSBitmapImageRep need to manually change frame. "Good taste" API
|
||||
[bitmapRep setProperty:NSImageCurrentFrame withValue:@(i)];
|
||||
float frameDuration = [[bitmapRep valueForProperty:NSImageCurrentFrameDuration] floatValue];
|
||||
NSImage *frameImage = [[NSImage alloc] initWithCGImage:bitmapRep.CGImage size:NSZeroSize];
|
||||
[bitmapImageRep setProperty:NSImageCurrentFrame withValue:@(i)];
|
||||
float frameDuration = [[bitmapImageRep valueForProperty:NSImageCurrentFrameDuration] floatValue];
|
||||
NSImage *frameImage = [[NSImage alloc] initWithCGImage:bitmapImageRep.CGImage scale:scale];
|
||||
SDWebImageFrame *frame = [SDWebImageFrame frameWithImage:frameImage duration:frameDuration];
|
||||
[frames addObject:frame];
|
||||
}
|
||||
|
|
|
@ -100,14 +100,6 @@
|
|||
if (!data) {
|
||||
return nil;
|
||||
}
|
||||
BOOL decodeFirstFrame = [[options valueForKey:SDWebImageCoderDecodeFirstFrameOnly] boolValue];
|
||||
CGFloat scale = 1;
|
||||
if ([options valueForKey:SDWebImageCoderDecodeScaleFactor]) {
|
||||
scale = [[options valueForKey:SDWebImageCoderDecodeScaleFactor] doubleValue];
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
}
|
||||
UIImage *image;
|
||||
for (id<SDWebImageCoder> coder in self.coders) {
|
||||
if ([coder canDecodeFromData:data]) {
|
||||
|
@ -115,16 +107,6 @@
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (image) {
|
||||
// Check static image
|
||||
if (decodeFirstFrame && image.images.count > 0) {
|
||||
image = image.images.firstObject;
|
||||
}
|
||||
// Check image scale
|
||||
if (scale > 1 && scale != image.scale) {
|
||||
image = SDScaledImageForScaleFactor(scale, image);
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
|
|
@ -88,18 +88,25 @@ inline UIImage * _Nullable SDScaledImageForScaleFactor(CGFloat scale, UIImage *
|
|||
animatedImage = [UIImage animatedImageWithImages:scaledImages duration:image.duration];
|
||||
animatedImage.sd_imageLoopCount = image.sd_imageLoopCount;
|
||||
#else
|
||||
// Animated GIF for `NSImage` need to grab `NSBitmapImageRep`
|
||||
NSSize size = NSMakeSize(image.size.width / scale, image.size.height / scale);
|
||||
animatedImage = [[NSImage alloc] initWithSize:size];
|
||||
NSBitmapImageRep *bitmapImageRep = image.bitmapImageRep;
|
||||
[animatedImage addRepresentation:bitmapImageRep];
|
||||
// Animated GIF for `NSImage` need to grab `NSBitmapImageRep`;
|
||||
NSRect imageRect = NSMakeRect(0, 0, image.size.width, image.size.height);
|
||||
NSImageRep *imageRep = [image bestRepresentationForRect:imageRect context:nil hints:nil];
|
||||
NSBitmapImageRep *bitmapImageRep;
|
||||
if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {
|
||||
bitmapImageRep = (NSBitmapImageRep *)imageRep;
|
||||
}
|
||||
if (bitmapImageRep) {
|
||||
NSSize size = NSMakeSize(image.size.width / scale, image.size.height / scale);
|
||||
animatedImage = [[NSImage alloc] initWithSize:size];
|
||||
[animatedImage addRepresentation:bitmapImageRep];
|
||||
}
|
||||
#endif
|
||||
scaledImage = animatedImage;
|
||||
} else {
|
||||
#if SD_UIKIT || SD_WATCH
|
||||
scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation];
|
||||
#else
|
||||
scaledImage = [[NSImage alloc] initWithCGImage:image.CGImage size:NSZeroSize];
|
||||
scaledImage = [[NSImage alloc] initWithCGImage:image.CGImage scale:scale];
|
||||
#endif
|
||||
}
|
||||
scaledImage.sd_isIncremental = image.sd_isIncremental;
|
||||
|
|
|
@ -72,10 +72,19 @@
|
|||
if (!data) {
|
||||
return nil;
|
||||
}
|
||||
CGFloat scale = 1;
|
||||
if ([options valueForKey:SDWebImageCoderDecodeScaleFactor]) {
|
||||
scale = [[options valueForKey:SDWebImageCoderDecodeScaleFactor] doubleValue];
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if SD_MAC
|
||||
SDAnimatedImageRep *imageRep = [[SDAnimatedImageRep alloc] initWithData:data];
|
||||
NSImage *animatedImage = [[NSImage alloc] initWithSize:imageRep.size];
|
||||
NSSize size = NSMakeSize(imageRep.pixelsWide / scale, imageRep.pixelsHigh / scale);
|
||||
imageRep.size = size;
|
||||
NSImage *animatedImage = [[NSImage alloc] initWithSize:size];
|
||||
[animatedImage addRepresentation:imageRep];
|
||||
return animatedImage;
|
||||
#else
|
||||
|
@ -85,13 +94,6 @@
|
|||
return nil;
|
||||
}
|
||||
size_t count = CGImageSourceGetCount(source);
|
||||
CGFloat scale = 1;
|
||||
if ([options valueForKey:SDWebImageCoderDecodeScaleFactor]) {
|
||||
scale = [[options valueForKey:SDWebImageCoderDecodeScaleFactor] doubleValue];
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
}
|
||||
UIImage *animatedImage;
|
||||
|
||||
BOOL decodeFirstFrame = [options[SDWebImageCoderDecodeFirstFrameOnly] boolValue];
|
||||
|
@ -224,10 +226,17 @@
|
|||
CGImageRef partialImageRef = CGImageSourceCreateImageAtIndex(_imageSource, 0, NULL);
|
||||
|
||||
if (partialImageRef) {
|
||||
CGFloat scale = 1;
|
||||
if ([options valueForKey:SDWebImageCoderDecodeScaleFactor]) {
|
||||
scale = [[options valueForKey:SDWebImageCoderDecodeScaleFactor] doubleValue];
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
}
|
||||
#if SD_UIKIT || SD_WATCH
|
||||
image = [[UIImage alloc] initWithCGImage:partialImageRef];
|
||||
image = [[UIImage alloc] initWithCGImage:partialImageRef scale:scale orientation:UIImageOrientationUp];
|
||||
#elif SD_MAC
|
||||
image = [[UIImage alloc] initWithCGImage:partialImageRef size:NSZeroSize];
|
||||
image = [[UIImage alloc] initWithCGImage:partialImageRef scale:scale];
|
||||
#endif
|
||||
CGImageRelease(partialImageRef);
|
||||
}
|
||||
|
@ -375,7 +384,7 @@
|
|||
CGImageRelease(imageRef);
|
||||
}
|
||||
#if SD_MAC
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:newImageRef size:NSZeroSize];
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:newImageRef scale:1];
|
||||
#else
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:newImageRef];
|
||||
#endif
|
||||
|
|
|
@ -81,11 +81,6 @@
|
|||
if (!data) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
#if SD_MAC
|
||||
UIImage *image = [[UIImage alloc] initWithData:data];
|
||||
return image;
|
||||
#else
|
||||
CGFloat scale = 1;
|
||||
if ([options valueForKey:SDWebImageCoderDecodeScaleFactor]) {
|
||||
scale = [[options valueForKey:SDWebImageCoderDecodeScaleFactor] doubleValue];
|
||||
|
@ -93,7 +88,11 @@
|
|||
scale = 1;
|
||||
}
|
||||
}
|
||||
|
||||
UIImage *image = [[UIImage alloc] initWithData:data scale:scale];
|
||||
#if SD_MAC
|
||||
return image;
|
||||
#else
|
||||
if (!image) {
|
||||
return nil;
|
||||
}
|
||||
|
@ -182,10 +181,17 @@
|
|||
#endif
|
||||
|
||||
if (partialImageRef) {
|
||||
CGFloat scale = 1;
|
||||
if ([options valueForKey:SDWebImageCoderDecodeScaleFactor]) {
|
||||
scale = [[options valueForKey:SDWebImageCoderDecodeScaleFactor] doubleValue];
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
}
|
||||
#if SD_UIKIT || SD_WATCH
|
||||
image = [[UIImage alloc] initWithCGImage:partialImageRef scale:1 orientation:_orientation];
|
||||
image = [[UIImage alloc] initWithCGImage:partialImageRef scale:scale orientation:_orientation];
|
||||
#elif SD_MAC
|
||||
image = [[UIImage alloc] initWithCGImage:partialImageRef size:NSZeroSize];
|
||||
image = [[UIImage alloc] initWithCGImage:partialImageRef scale:scale];
|
||||
#endif
|
||||
CGImageRelease(partialImageRef);
|
||||
}
|
||||
|
|
|
@ -261,7 +261,7 @@
|
|||
|
||||
if (options & SDWebImageRefreshCached && cachedImage && !downloadedImage) {
|
||||
// Image refresh hit the NSURLCache cache, do not call the completion block
|
||||
} else if (downloadedImage && (!downloadedImage.images || (options & SDWebImageTransformAnimatedImage)) && transformer) {
|
||||
} else if (downloadedImage && (!downloadedImage.sd_isAnimated || (options & SDWebImageTransformAnimatedImage)) && transformer) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||
UIImage *transformedImage = [transformer transformedImageWithImage:downloadedImage forKey:key];
|
||||
if (transformedImage && finished) {
|
||||
|
|
|
@ -114,7 +114,6 @@ dispatch_semaphore_signal(self->_lock);
|
|||
uint32_t flags = WebPDemuxGetI(demuxer, WEBP_FF_FORMAT_FLAGS);
|
||||
BOOL hasAnimation = flags & ANIMATION_FLAG;
|
||||
BOOL decodeFirstFrame = [[options valueForKey:SDWebImageCoderDecodeFirstFrameOnly] boolValue];
|
||||
#if SD_UIKIT || SD_WATCH
|
||||
CGFloat scale = 1;
|
||||
if ([options valueForKey:SDWebImageCoderDecodeScaleFactor]) {
|
||||
scale = [[options valueForKey:SDWebImageCoderDecodeScaleFactor] doubleValue];
|
||||
|
@ -122,7 +121,6 @@ dispatch_semaphore_signal(self->_lock);
|
|||
scale = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!hasAnimation) {
|
||||
// for static single webp image
|
||||
CGImageRef imageRef = [self sd_createWebpImageWithData:webpData];
|
||||
|
@ -132,7 +130,7 @@ dispatch_semaphore_signal(self->_lock);
|
|||
#if SD_UIKIT || SD_WATCH
|
||||
UIImage *staticImage = [[UIImage alloc] initWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp];
|
||||
#else
|
||||
UIImage *staticImage = [[UIImage alloc] initWithCGImage:imageRef size:NSZeroSize];
|
||||
UIImage *staticImage = [[UIImage alloc] initWithCGImage:imageRef scale:scale];
|
||||
#endif
|
||||
CGImageRelease(imageRef);
|
||||
WebPDemuxDelete(demuxer);
|
||||
|
@ -154,7 +152,7 @@ dispatch_semaphore_signal(self->_lock);
|
|||
#if SD_UIKIT || SD_WATCH
|
||||
UIImage *firstFrameImage = [[UIImage alloc] initWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp];
|
||||
#else
|
||||
UIImage *firstFrameImage = [[UIImage alloc] initWithCGImage:imageRef size:NSZeroSize];
|
||||
UIImage *firstFrameImage = [[UIImage alloc] initWithCGImage:imageRef scale:scale];
|
||||
#endif
|
||||
CGImageRelease(imageRef);
|
||||
WebPDemuxReleaseIterator(&iter);
|
||||
|
@ -185,7 +183,7 @@ dispatch_semaphore_signal(self->_lock);
|
|||
#if SD_UIKIT || SD_WATCH
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp];
|
||||
#else
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef size:NSZeroSize];
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef scale:scale];
|
||||
#endif
|
||||
CGImageRelease(imageRef);
|
||||
|
||||
|
@ -279,11 +277,18 @@ dispatch_semaphore_signal(self->_lock);
|
|||
CGContextRelease(canvas);
|
||||
return nil;
|
||||
}
|
||||
CGFloat scale = 1;
|
||||
if ([options valueForKey:SDWebImageCoderDecodeScaleFactor]) {
|
||||
scale = [[options valueForKey:SDWebImageCoderDecodeScaleFactor] doubleValue];
|
||||
if (scale < 1) {
|
||||
scale = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if SD_UIKIT || SD_WATCH
|
||||
image = [[UIImage alloc] initWithCGImage:newImageRef];
|
||||
image = [[UIImage alloc] initWithCGImage:newImageRef scale:scale orientation:UIImageOrientationUp];
|
||||
#else
|
||||
image = [[UIImage alloc] initWithCGImage:newImageRef size:NSZeroSize];
|
||||
image = [[UIImage alloc] initWithCGImage:newImageRef scale:scale];
|
||||
#endif
|
||||
CGImageRelease(newImageRef);
|
||||
CGContextRelease(canvas);
|
||||
|
@ -664,7 +669,7 @@ static void FreeImageData(void *info, const void *data, size_t size) {
|
|||
#if SD_UIKIT || SD_WATCH
|
||||
image = [[UIImage alloc] initWithCGImage:imageRef];
|
||||
#else
|
||||
image = [[UIImage alloc] initWithCGImage:imageRef size:NSZeroSize];
|
||||
image = [[UIImage alloc] initWithCGImage:imageRef scale:1];
|
||||
#endif
|
||||
CGImageRelease(imageRef);
|
||||
} else {
|
||||
|
@ -694,7 +699,7 @@ static void FreeImageData(void *info, const void *data, size_t size) {
|
|||
#if SD_UIKIT || SD_WATCH
|
||||
image = [[UIImage alloc] initWithCGImage:imageRef];
|
||||
#else
|
||||
image = [[UIImage alloc] initWithCGImage:imageRef size:NSZeroSize];
|
||||
image = [[UIImage alloc] initWithCGImage:imageRef scale:1];
|
||||
#endif
|
||||
CGImageRelease(imageRef);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,15 @@ static CGContextRef SDCGContextCreateARGBBitmapContext(CGSize size, BOOL opaque,
|
|||
CGImageAlphaInfo alphaInfo = (opaque ? kCGImageAlphaNoneSkipFirst : kCGImageAlphaPremultipliedFirst);
|
||||
CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, 0, space, kCGBitmapByteOrderDefault | alphaInfo);
|
||||
CGColorSpaceRelease(space);
|
||||
if (!context) {
|
||||
return NULL;
|
||||
}
|
||||
if (scale == 0) {
|
||||
// Match `UIGraphicsBeginImageContextWithOptions`, reset to the scale factor of the device’s main screen if scale is 0.
|
||||
scale = [NSScreen mainScreen].backingScaleFactor;
|
||||
}
|
||||
CGContextScaleCTM(context, scale, scale);
|
||||
|
||||
return context;
|
||||
}
|
||||
#endif
|
||||
|
@ -71,7 +80,17 @@ static UIImage * SDGraphicsGetImageFromCurrentImageContext(void) {
|
|||
if (!imageRef) {
|
||||
return nil;
|
||||
}
|
||||
NSImage *image = [[NSImage alloc] initWithCGImage:imageRef size:NSZeroSize];
|
||||
CGAffineTransform transform = CGContextGetCTM(context);
|
||||
CGFloat xs = transform.a;
|
||||
CGFloat ys = transform.d;
|
||||
CGFloat scale;
|
||||
if (xs == ys && xs > 0) {
|
||||
scale = xs;
|
||||
} else {
|
||||
// Protect if x/y axis scale factor not equal
|
||||
scale = [NSScreen mainScreen].backingScaleFactor;
|
||||
}
|
||||
NSImage *image = [[NSImage alloc] initWithCGImage:imageRef scale:scale];
|
||||
CGImageRelease(imageRef);
|
||||
return image;
|
||||
#endif
|
||||
|
@ -303,7 +322,7 @@ static inline UIColor * SDGetColorFromPixel(Pixel_8888 pixel, CGBitmapInfo bitma
|
|||
#if SD_UIKIT || SD_WATCH
|
||||
UIImage *image = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation];
|
||||
#else
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef size:NSZeroSize];
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef scale:self.scale];
|
||||
#endif
|
||||
CGImageRelease(imageRef);
|
||||
return image;
|
||||
|
@ -381,7 +400,7 @@ static inline UIColor * SDGetColorFromPixel(Pixel_8888 pixel, CGBitmapInfo bitma
|
|||
#if SD_UIKIT || SD_WATCH
|
||||
UIImage *img = [UIImage imageWithCGImage:imgRef scale:self.scale orientation:self.imageOrientation];
|
||||
#else
|
||||
UIImage *img = [[UIImage alloc] initWithCGImage:imgRef size:NSZeroSize];
|
||||
UIImage *img = [[UIImage alloc] initWithCGImage:imgRef scale:self.scale];
|
||||
#endif
|
||||
CGImageRelease(imgRef);
|
||||
CGContextRelease(context);
|
||||
|
@ -417,7 +436,7 @@ static inline UIColor * SDGetColorFromPixel(Pixel_8888 pixel, CGBitmapInfo bitma
|
|||
#if SD_UIKIT || SD_WATCH
|
||||
UIImage *img = [UIImage imageWithCGImage:imgRef scale:self.scale orientation:self.imageOrientation];
|
||||
#else
|
||||
UIImage *img = [[UIImage alloc] initWithCGImage:imgRef size:NSZeroSize];
|
||||
UIImage *img = [[UIImage alloc] initWithCGImage:imgRef scale:self.scale];
|
||||
#endif
|
||||
CGImageRelease(imgRef);
|
||||
return img;
|
||||
|
@ -434,7 +453,7 @@ static inline UIColor * SDGetColorFromPixel(Pixel_8888 pixel, CGBitmapInfo bitma
|
|||
#if SD_UIKIT || SD_WATCH
|
||||
return [UIImage imageWithCGImage:self.CGImage scale:self.scale orientation:self.imageOrientation];
|
||||
#else
|
||||
return [[UIImage alloc] initWithCGImage:self.CGImage size:NSZeroSize];
|
||||
return [[UIImage alloc] initWithCGImage:self.CGImage scale:self.scale];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -651,7 +670,7 @@ static inline UIColor * SDGetColorFromPixel(Pixel_8888 pixel, CGBitmapInfo bitma
|
|||
#if SD_UIKIT || SD_WATCH
|
||||
UIImage *outputImage = [UIImage imageWithCGImage:effectCGImage scale:self.scale orientation:self.imageOrientation];
|
||||
#else
|
||||
UIImage *outputImage = [[UIImage alloc] initWithCGImage:effectCGImage size:NSZeroSize];
|
||||
UIImage *outputImage = [[UIImage alloc] initWithCGImage:effectCGImage scale:self.scale];
|
||||
#endif
|
||||
CGImageRelease(effectCGImage);
|
||||
|
||||
|
@ -676,7 +695,7 @@ static inline UIColor * SDGetColorFromPixel(Pixel_8888 pixel, CGBitmapInfo bitma
|
|||
#if SD_UIKIT
|
||||
UIImage *image = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation];
|
||||
#else
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef size:NSZeroSize];
|
||||
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef scale:self.scale];
|
||||
#endif
|
||||
CGImageRelease(imageRef);
|
||||
|
||||
|
|
|
@ -51,7 +51,12 @@
|
|||
|
||||
- (NSUInteger)sd_imageLoopCount {
|
||||
NSUInteger imageLoopCount = 0;
|
||||
NSBitmapImageRep *bitmapImageRep = self.bitmapImageRep;
|
||||
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) {
|
||||
imageLoopCount = [[bitmapImageRep valueForProperty:NSImageLoopCount] unsignedIntegerValue];
|
||||
}
|
||||
|
@ -59,7 +64,12 @@
|
|||
}
|
||||
|
||||
- (void)setSd_imageLoopCount:(NSUInteger)sd_imageLoopCount {
|
||||
NSBitmapImageRep *bitmapImageRep = self.bitmapImageRep;
|
||||
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) {
|
||||
[bitmapImageRep setProperty:NSImageLoopCount withValue:@(sd_imageLoopCount)];
|
||||
}
|
||||
|
@ -67,7 +77,12 @@
|
|||
|
||||
- (BOOL)sd_isAnimated {
|
||||
BOOL isGIF = NO;
|
||||
NSBitmapImageRep *bitmapImageRep = self.bitmapImageRep;
|
||||
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) {
|
||||
NSUInteger frameCount = [[bitmapImageRep valueForProperty:NSImageFrameCount] unsignedIntegerValue];
|
||||
isGIF = frameCount > 1 ? YES : NO;
|
||||
|
|
|
@ -170,7 +170,9 @@
|
|||
UIImage *outputImage = [coder decodedImageWithData:outputImageData options:nil];
|
||||
expect(outputImage.size).to.equal(inputImage.size);
|
||||
expect(outputImage.scale).to.equal(inputImage.scale);
|
||||
#if SD_UIKIT
|
||||
expect(outputImage.images.count).to.equal(inputImage.images.count);
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue