Merge branch 'feature_scale_factor' into 5.x

This commit is contained in:
DreamPiggy 2018-04-15 13:52:03 +08:00
commit 1367b18b89
5 changed files with 48 additions and 33 deletions

View File

@ -27,7 +27,7 @@ The underlying Core Graphics image object. This will actually use `CGImageForPro
/**
Returns an image object with the scale factor and orientation. The representation is created from the Core Graphics image object.
@note The difference between this and `initWithCGImage:size` is that `initWithCGImage:size` will use `backingScaleFactor` as scale factor if you specify `NSZeroSize` and does not support orientation.
@note The difference between this and `initWithCGImage:size` is that `initWithCGImage:size` will actually create a `NSCGImageSnapshotRep` representation and always use `backingScaleFactor` as scale factor. So we should avoid it and use `NSBitmapImageRep` with `initWithCGImage:` instead.
@note The difference between this and UIKit's `UIImage` equivalent method is the way to process orientation. If the provided image orientation is not equal to Up orientation, this method will firstly rotate the CGImage to the correct orientation to work compatible with `NSImageView`. However, UIKit will not actually rotate CGImage and just store it as `imageOrientation` property.
@param cgImage A Core Graphics image object

View File

@ -41,20 +41,26 @@
}
- (instancetype)initWithCGImage:(CGImageRef)cgImage scale:(CGFloat)scale orientation:(CGImagePropertyOrientation)orientation {
if (scale < 1) {
scale = 1;
}
CGFloat pixelWidth = CGImageGetWidth(cgImage);
CGFloat pixelHeight = CGImageGetHeight(cgImage);
NSSize size = NSMakeSize(pixelWidth / scale, pixelHeight / scale);
NSBitmapImageRep *imageRep;
if (orientation != kCGImagePropertyOrientationUp) {
// AppKit design is different from UIKit. Where CGImage based image rep does not respect to any orientation. Only data based image rep which contains the EXIF metadata can automatically detect orientation.
// This should be nonnull, until the memory is exhausted cause `CGBitmapContextCreate` failed.
cgImage = [SDWebImageCoderHelper CGImageCreateDecoded:cgImage orientation:orientation];
self = [self initWithCGImage:cgImage size:size];
CGImageRelease(cgImage);
CGImageRef rotatedCGImage = [SDWebImageCoderHelper CGImageCreateDecoded:cgImage orientation:orientation];
imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
CGImageRelease(rotatedCGImage);
} else {
self = [self initWithCGImage:cgImage size:size];
imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
}
if (scale < 1) {
scale = 1;
}
CGFloat pixelWidth = imageRep.pixelsWide;
CGFloat pixelHeight = imageRep.pixelsHigh;
NSSize size = NSMakeSize(pixelWidth / scale, pixelHeight / scale);
self = [self initWithSize:size];
if (self) {
imageRep.size = size;
[self addRepresentation:imageRep];
}
return self;
}

View File

@ -69,7 +69,8 @@
@property (nonatomic, assign, readonly) SDImageFormat animatedImageFormat;
/**
Current animated image data, you can use this instead of CGImage to create another instance
Current animated image data, you can use this instead of CGImage to create another instance.
If the current image is not animated image, this value is nil.
*/
@property (nonatomic, copy, readonly, nullable) NSData *animatedImageData;
@ -77,7 +78,7 @@
The scale factor of the image.
@note For UIKit, this just call super instead.
@note For AppKit, `NSImage` can contains multiple image representations with different scales. However, this class does not do that from the design. We processs the scale like UIKit and store it as a extra information for correctlly rendering in `SDAnimatedImageView`.
@note For AppKit, `NSImage` can contains multiple image representations with different scales. However, this class does not do that from the design. We processs the scale like UIKit. This wil actually be calculated from image size and pixel size.
*/
@property (nonatomic, readonly) CGFloat scale;

View File

@ -205,9 +205,7 @@ static NSArray *SDBundlePreferredScales() {
@end
@implementation SDAnimatedImage
#if SD_UIKIT || SD_WATCH
@dynamic scale; // call super
#endif
#pragma mark - UIImage override method
+ (instancetype)imageNamed:(NSString *)name {
@ -316,9 +314,6 @@ static NSArray *SDBundlePreferredScales() {
#endif
if (self) {
_coder = animatedCoder;
#if SD_MAC
_scale = scale;
#endif
NSData *data = [animatedCoder animatedImageData];
SDImageFormat format = [NSData sd_imageFormatForImageData:data];
_animatedImageFormat = format;
@ -350,24 +345,37 @@ static NSArray *SDBundlePreferredScales() {
#pragma mark - NSSecureCoding
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
NSNumber *scale = [aDecoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(scale))];
self = [super initWithCoder:aDecoder];
if (self) {
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];
CGFloat scale = self.scale;
if (!animatedImageData) {
return self;
}
id<SDWebImageAnimatedCoder> animatedCoder = nil;
for (id<SDWebImageCoder>coder in [SDWebImageCodersManager sharedManager].coders) {
if ([coder conformsToProtocol:@protocol(SDWebImageAnimatedCoder)]) {
if ([coder canDecodeFromData:animatedImageData]) {
animatedCoder = [[[coder class] alloc] initWithAnimatedImageData:animatedImageData options:@{SDWebImageCoderDecodeScaleFactor : @(scale)}];
break;
}
}
}
if (!animatedCoder) {
return self;
}
_coder = animatedCoder;
SDImageFormat format = [NSData sd_imageFormatForImageData:animatedImageData];
_animatedImageFormat = format;
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
if (self.animatedImageData) {
[aCoder encodeObject:self.animatedImageData forKey:NSStringFromSelector(@selector(animatedImageData))];
[aCoder encodeObject:@(self.scale) forKey:NSStringFromSelector(@selector(scale))];
} else {
[super encodeWithCoder:aCoder];
NSData *animatedImageData = self.animatedImageData;
if (animatedImageData) {
[aCoder encodeObject:animatedImageData forKey:NSStringFromSelector(@selector(animatedImageData))];
}
}

View File

@ -99,7 +99,7 @@
BOOL decodeFirstFrame = [options[SDWebImageCoderDecodeFirstFrameOnly] boolValue];
if (decodeFirstFrame || count <= 1) {
animatedImage = [[UIImage alloc] initWithData:data];
animatedImage = [[UIImage alloc] initWithData:data scale:scale];
} else {
NSMutableArray<SDWebImageFrame *> *frames = [NSMutableArray array];