Behavior changes: change the default tint transformer to use `sourceIn` instead of `sourceAtop`
This matches the Apple UIKit's naming and behavior
This commit is contained in:
parent
7892f4ca20
commit
05e1840538
|
@ -223,7 +223,7 @@ FOUNDATION_EXPORT NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullab
|
||||||
The tint color.
|
The tint color.
|
||||||
*/
|
*/
|
||||||
@property (nonatomic, strong, readonly, nonnull) UIColor *tintColor;
|
@property (nonatomic, strong, readonly, nonnull) UIColor *tintColor;
|
||||||
/// The blend mode, defaults to `sourceAtop` if you use the old initializer
|
/// The blend mode, defaults to `sourceIn` if you use the initializer without blend mode
|
||||||
@property (nonatomic, assign, readonly) CGBlendMode blendMode;
|
@property (nonatomic, assign, readonly) CGBlendMode blendMode;
|
||||||
|
|
||||||
- (nonnull instancetype)init NS_UNAVAILABLE;
|
- (nonnull instancetype)init NS_UNAVAILABLE;
|
||||||
|
|
|
@ -252,7 +252,7 @@ NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullable key, CGSize thu
|
||||||
@implementation SDImageTintTransformer
|
@implementation SDImageTintTransformer
|
||||||
|
|
||||||
+ (instancetype)transformerWithColor:(UIColor *)tintColor {
|
+ (instancetype)transformerWithColor:(UIColor *)tintColor {
|
||||||
return [self transformerWithColor:tintColor blendMode:kCGBlendModeSourceAtop];
|
return [self transformerWithColor:tintColor blendMode:kCGBlendModeSourceIn];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (instancetype)transformerWithColor:(UIColor *)tintColor blendMode:(CGBlendMode)blendMode {
|
+ (instancetype)transformerWithColor:(UIColor *)tintColor blendMode:(CGBlendMode)blendMode {
|
||||||
|
|
|
@ -98,7 +98,8 @@ typedef NS_OPTIONS(NSUInteger, SDRectCorner) {
|
||||||
#pragma mark - Image Blending
|
#pragma mark - Image Blending
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return a tinted image with the given color. This actually use `sourceAtop` blend mode.
|
Return a tinted image with the given color. This actually use `sourceIn` blend mode.
|
||||||
|
@note Before 5.20, this API actually use `sourceAtop` and cause naming confusing. After 5.20, we match UIKit's behavior using `sourceIn`.
|
||||||
|
|
||||||
@param tintColor The tint color.
|
@param tintColor The tint color.
|
||||||
@return The new image with the tint color.
|
@return The new image with the tint color.
|
||||||
|
@ -107,7 +108,7 @@ typedef NS_OPTIONS(NSUInteger, SDRectCorner) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return a tinted image with the given color and blend mode.
|
Return a tinted image with the given color and blend mode.
|
||||||
@note The blend mode treat `self` as background image (destination), treat `tintColor` as input image (source). So mostly you need `source` variant blend mode (use `sourceAtop` not `destinationAtop`).
|
@note The blend mode treat `self` as background image (destination), treat `tintColor` as input image (source). So mostly you need `source` variant blend mode (use `sourceIn` not `destinationIn`), which is different from UIKit's `+[UIImage imageWithTintColor:]`.
|
||||||
|
|
||||||
@param tintColor The tint color.
|
@param tintColor The tint color.
|
||||||
@param blendMode The blend mode.
|
@param blendMode The blend mode.
|
||||||
|
|
|
@ -627,7 +627,7 @@ static NSString * _Nullable SDGetCIFilterNameFromBlendMode(CGBlendMode blendMode
|
||||||
}
|
}
|
||||||
|
|
||||||
- (nullable UIImage *)sd_tintedImageWithColor:(nonnull UIColor *)tintColor {
|
- (nullable UIImage *)sd_tintedImageWithColor:(nonnull UIColor *)tintColor {
|
||||||
return [self sd_tintedImageWithColor:tintColor blendMode:kCGBlendModeSourceAtop];
|
return [self sd_tintedImageWithColor:tintColor blendMode:kCGBlendModeSourceIn];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (nullable UIImage *)sd_tintedImageWithColor:(nonnull UIColor *)tintColor blendMode:(CGBlendMode)blendMode {
|
- (nullable UIImage *)sd_tintedImageWithColor:(nonnull UIColor *)tintColor blendMode:(CGBlendMode)blendMode {
|
||||||
|
@ -694,7 +694,7 @@ static NSString * _Nullable SDGetCIFilterNameFromBlendMode(CGBlendMode blendMode
|
||||||
// MAX
|
// MAX
|
||||||
ciImage = [ciImage imageByApplyingFilter:@"CIColorClamp" withInputParameters:nil];
|
ciImage = [ciImage imageByApplyingFilter:@"CIColorClamp" withInputParameters:nil];
|
||||||
} else {
|
} else {
|
||||||
SD_LOG("UIImage+Transform error: Unsupported blend mode: %zu", blendMode);
|
SD_LOG("UIImage+Transform error: Unsupported blend mode: %d", blendMode);
|
||||||
ciImage = nil;
|
ciImage = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,9 +244,33 @@ static void SDAssertCGImageFirstComponentWhite(CGImageRef image, OSType pixelTyp
|
||||||
expect([topCenterColor.sd_hexString isEqualToString:[UIColor blackColor].sd_hexString]).beTruthy();
|
expect([topCenterColor.sd_hexString isEqualToString:[UIColor blackColor].sd_hexString]).beTruthy();
|
||||||
|
|
||||||
UIImage *tintedSourceInImage = [testImage sd_tintedImageWithColor:tintColor blendMode:kCGBlendModeSourceIn];
|
UIImage *tintedSourceInImage = [testImage sd_tintedImageWithColor:tintColor blendMode:kCGBlendModeSourceIn];
|
||||||
centerColor = [tintedSourceInImage sd_colorAtPoint:CGPointMake(150, 150)];
|
topCenterColor = [tintedSourceInImage sd_colorAtPoint:CGPointMake(150, 20)];
|
||||||
expect([centerColor.sd_hexString isEqualToString:[UIColor blackColor].sd_hexString]).beTruthy();
|
#if SD_UIKIT
|
||||||
|
// Test UIKit's tint color behavior
|
||||||
|
if (@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)) {
|
||||||
|
UIImage *tintedSystemImage = [testImage imageWithTintColor:tintColor renderingMode:UIImageRenderingModeAlwaysTemplate];
|
||||||
|
UIGraphicsImageRendererFormat *format = UIGraphicsImageRendererFormat.preferredFormat;
|
||||||
|
format.scale = tintedSourceInImage.scale;
|
||||||
|
UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:tintedSystemImage.size format:format];
|
||||||
|
// Draw template image
|
||||||
|
tintedSystemImage = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
|
||||||
|
[tintedSystemImage drawInRect:CGRectMake(0, 0, tintedSystemImage.size.width, tintedSystemImage.size.height)];
|
||||||
|
}];
|
||||||
|
UIColor *testColor1 = [tintedSourceInImage sd_colorAtPoint:CGPointMake(150, 20)];
|
||||||
|
UIColor *testColor2 = [tintedSystemImage sd_colorAtPoint:CGPointMake(150, 20)];
|
||||||
|
CGFloat r1, g1, b1, a1;
|
||||||
|
CGFloat r2, g2, b2, a2;
|
||||||
|
[testColor1 getRed:&r1 green:&g1 blue:&b1 alpha:&a1];
|
||||||
|
[testColor2 getRed:&r2 green:&g2 blue:&b2 alpha:&a2];
|
||||||
|
expect(r1).beCloseToWithin(r2, 0.01);
|
||||||
|
expect(g1).beCloseToWithin(g2, 0.01);
|
||||||
|
expect(b1).beCloseToWithin(b2, 0.01);
|
||||||
|
expect(a1).beCloseToWithin(a2, 0.01);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
expect([topCenterColor.sd_hexString isEqualToString:tintColor.sd_hexString]).beTruthy();
|
||||||
}
|
}
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
|
||||||
- (void)test07UIImageTransformBlurCG {
|
- (void)test07UIImageTransformBlurCG {
|
||||||
[self test07UIImageTransformBlurWithImage:self.testImageCG];
|
[self test07UIImageTransformBlurWithImage:self.testImageCG];
|
||||||
|
@ -357,7 +381,7 @@ static void SDAssertCGImageFirstComponentWhite(CGImageRef image, OSType pixelTyp
|
||||||
@"SDImageRoundCornerTransformer(50.000000,18446744073709551615,1.000000,#ff000000)",
|
@"SDImageRoundCornerTransformer(50.000000,18446744073709551615,1.000000,#ff000000)",
|
||||||
@"SDImageFlippingTransformer(1,1)",
|
@"SDImageFlippingTransformer(1,1)",
|
||||||
@"SDImageCroppingTransformer({0.000000,0.000000,50.000000,50.000000})",
|
@"SDImageCroppingTransformer({0.000000,0.000000,50.000000,50.000000})",
|
||||||
@"SDImageTintTransformer(#00000000,20)",
|
@"SDImageTintTransformer(#00000000,18)",
|
||||||
@"SDImageBlurTransformer(5.000000)",
|
@"SDImageBlurTransformer(5.000000)",
|
||||||
@"SDImageFilterTransformer(CIColorInvert)"
|
@"SDImageFilterTransformer(CIColorInvert)"
|
||||||
];
|
];
|
||||||
|
|
Loading…
Reference in New Issue