Update the transformer to use as immutable class. Move the tests into SDWebImageTransformerTests

This commit is contained in:
DreamPiggy 2018-03-23 01:45:53 +08:00
parent ed0100c323
commit ec7927b25a
6 changed files with 302 additions and 209 deletions

View File

@ -48,18 +48,18 @@ FOUNDATION_EXPORT NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullab
#pragma mark - Pipeline
// Pipeline transformer. Which you can bind multiple transformers together to let the image to be transformed one by one in order and generate the final image.
// Because transformers are lightweight, if you want to append or arrange transfomers, create another pipeline transformer instead. This class is considered as immutable.
@interface SDWebImagePipelineTransformer : NSObject <SDWebImageTransformer>
@property (nonatomic, copy, readonly, nonnull) NSArray<id<SDWebImageTransformer>> *transformers;
- (nonnull instancetype)initWithTransformers:(nonnull NSArray<id<SDWebImageTransformer>> *)transformers;
- (void)addTransformer:(nonnull id<SDWebImageTransformer>)transformer;
- (void)removeTransformer:(nonnull id<SDWebImageTransformer>)transformer;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithTransformers:(nonnull NSArray<id<SDWebImageTransformer>> *)transformers;
@end
// There are some build-in transformer based on the `UIImage+Transformer` category to provide the common image geometry, image blending and image effect process. Those transform are useful for static image only but you can create your own to support animated image as well.
// There are some built-in transformers based on the `UIImage+Transformer` category to provide the common image geometry, image blending and image effect process. Those transform are useful for static image only but you can create your own to support animated image as well.
// Because transformers are lightweight, these class are considered as immutable.
#pragma mark - Image Geometry
// Image round corner transformer
@ -70,7 +70,8 @@ FOUNDATION_EXPORT NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullab
@property (nonatomic, assign, readonly) CGFloat borderWidth;
@property (nonatomic, strong, readonly, nullable) UIColor *borderColor;
- (nonnull instancetype)initWithRadius:(CGFloat)cornerRadius corners:(SDRectCorner)corners borderWidth:(CGFloat)borderWidth borderColor:(nullable UIColor *)borderColor;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithRadius:(CGFloat)cornerRadius corners:(SDRectCorner)corners borderWidth:(CGFloat)borderWidth borderColor:(nullable UIColor *)borderColor;
@end
@ -80,7 +81,8 @@ FOUNDATION_EXPORT NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullab
@property (nonatomic, assign, readonly) CGSize size;
@property (nonatomic, assign, readonly) SDImageScaleMode scaleMode;
- (nonnull instancetype)initWithSize:(CGSize)size scaleMode:(SDImageScaleMode)scaleMode;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithSize:(CGSize)size scaleMode:(SDImageScaleMode)scaleMode;
@end
@ -89,7 +91,8 @@ FOUNDATION_EXPORT NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullab
@property (nonatomic, assign, readonly) CGRect rect;
- (nonnull instancetype)initWithRect:(CGRect)rect;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithRect:(CGRect)rect;
@end
@ -99,7 +102,8 @@ FOUNDATION_EXPORT NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullab
@property (nonatomic, assign, readonly) BOOL horizontal;
@property (nonatomic, assign, readonly) BOOL vertical;
- (nonnull instancetype)initWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical;
@end
@ -109,7 +113,8 @@ FOUNDATION_EXPORT NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullab
@property (nonatomic, assign, readonly) CGFloat angle;
@property (nonatomic, assign, readonly) BOOL fitSize;
- (nonnull instancetype)initWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize;
@end
@ -120,7 +125,8 @@ FOUNDATION_EXPORT NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullab
@property (nonatomic, strong, readonly, nonnull) UIColor *tintColor;
- (nonnull instancetype)initWithColor:(nonnull UIColor *)tintColor;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithColor:(nonnull UIColor *)tintColor;
@end
@ -131,7 +137,8 @@ FOUNDATION_EXPORT NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullab
@property (nonatomic, assign, readonly) CGFloat blurRadius;
- (nonnull instancetype)initWithRadius:(CGFloat)blurRadius;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithRadius:(CGFloat)blurRadius;
@end
@ -141,7 +148,8 @@ FOUNDATION_EXPORT NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullab
@property (nonatomic, strong, readonly, nonnull) CIFilter *filter;
- (nonnull instancetype)initWithFilter:(nonnull CIFilter *)filter;
- (nonnull instancetype)init NS_UNAVAILABLE;
+ (nonnull instancetype)transformerWithFilter:(nonnull CIFilter *)filter;
@end
#endif

View File

@ -72,13 +72,12 @@ NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString *
@implementation SDWebImagePipelineTransformer
- (instancetype)initWithTransformers:(NSArray<id<SDWebImageTransformer>> *)transformers {
self = [super init];
if (self) {
_transformers = [transformers copy];
_transformerKey = [[self class] cacheKeyForTransformers:transformers];
}
return self;
+ (instancetype)transformerWithTransformers:(NSArray<id<SDWebImageTransformer>> *)transformers {
SDWebImagePipelineTransformer *transformer = [SDWebImagePipelineTransformer new];
transformer.transformers = transformers;
transformer.transformerKey = [[self class] cacheKeyForTransformers:transformers];
return transformer;
}
+ (NSString *)cacheKeyForTransformers:(NSArray<id<SDWebImageTransformer>> *)transformers {
@ -105,35 +104,27 @@ NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString *
return transformedImage;
}
- (void)addTransformer:(id<SDWebImageTransformer>)transformer {
if (!transformer) {
return;
}
self.transformers = [self.transformers arrayByAddingObject:transformer];
}
@end
- (void)removeTransformer:(id<SDWebImageTransformer>)transformer {
if (!transformer) {
return;
}
NSMutableArray<id<SDWebImageTransformer>> *transformers = [self.transformers mutableCopy];
[transformers removeObject:transformer];
self.transformers = [transformers copy];
}
@interface SDWebImageRoundCornerTransformer ()
@property (nonatomic, assign) CGFloat cornerRadius;
@property (nonatomic, assign) SDRectCorner corners;
@property (nonatomic, assign) CGFloat borderWidth;
@property (nonatomic, strong, nullable) UIColor *borderColor;
@end
@implementation SDWebImageRoundCornerTransformer
- (instancetype)initWithRadius:(CGFloat)cornerRadius corners:(SDRectCorner)corners borderWidth:(CGFloat)borderWidth borderColor:(nullable UIColor *)borderColor {
self = [super init];
if (self) {
_cornerRadius = cornerRadius;
_corners = corners;
_borderWidth = borderWidth;
_borderColor = borderColor;
}
return self;
+ (instancetype)transformerWithRadius:(CGFloat)cornerRadius corners:(SDRectCorner)corners borderWidth:(CGFloat)borderWidth borderColor:(UIColor *)borderColor {
SDWebImageRoundCornerTransformer *transformer = [SDWebImageRoundCornerTransformer new];
transformer.cornerRadius = cornerRadius;
transformer.corners = corners;
transformer.borderWidth = borderWidth;
transformer.borderColor = borderColor;
return transformer;
}
- (NSString *)transformerKey {
@ -149,15 +140,21 @@ NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString *
@end
@interface SDWebImageResizingTransformer ()
@property (nonatomic, assign) CGSize size;
@property (nonatomic, assign) SDImageScaleMode scaleMode;
@end
@implementation SDWebImageResizingTransformer
- (instancetype)initWithSize:(CGSize)size scaleMode:(SDImageScaleMode)scaleMode {
self = [super init];
if (self) {
_size = size;
_scaleMode = scaleMode;
}
return self;
+ (instancetype)transformerWithSize:(CGSize)size scaleMode:(SDImageScaleMode)scaleMode {
SDWebImageResizingTransformer *transformer = [SDWebImageResizingTransformer new];
transformer.size = size;
transformer.scaleMode = scaleMode;
return transformer;
}
- (NSString *)transformerKey {
@ -174,14 +171,19 @@ NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString *
@end
@interface SDWebImageCroppingTransformer ()
@property (nonatomic, assign) CGRect rect;
@end
@implementation SDWebImageCroppingTransformer
- (instancetype)initWithRect:(CGRect)rect {
self = [super init];
if (self) {
_rect = rect;
}
return self;
+ (instancetype)transformerWithRect:(CGRect)rect {
SDWebImageCroppingTransformer *transformer = [SDWebImageCroppingTransformer new];
transformer.rect = rect;
return transformer;
}
- (NSString *)transformerKey {
@ -198,15 +200,21 @@ NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString *
@end
@interface SDWebImageFlippingTransformer ()
@property (nonatomic, assign) BOOL horizontal;
@property (nonatomic, assign) BOOL vertical;
@end
@implementation SDWebImageFlippingTransformer
- (instancetype)initWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical {
self = [super init];
if (self) {
_horizontal = horizontal;
_vertical = vertical;
}
return self;
+ (instancetype)transformerWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical {
SDWebImageFlippingTransformer *transformer = [SDWebImageFlippingTransformer new];
transformer.horizontal = horizontal;
transformer.vertical = vertical;
return transformer;
}
- (NSString *)transformerKey {
@ -222,15 +230,21 @@ NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString *
@end
@interface SDWebImageRotationTransformer ()
@property (nonatomic, assign) CGFloat angle;
@property (nonatomic, assign) BOOL fitSize;
@end
@implementation SDWebImageRotationTransformer
- (instancetype)initWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize {
self = [super init];
if (self) {
_angle = angle;
_fitSize = fitSize;
}
return self;
+ (instancetype)transformerWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize {
SDWebImageRotationTransformer *transformer = [SDWebImageRotationTransformer new];
transformer.angle = angle;
transformer.fitSize = fitSize;
return transformer;
}
- (NSString *)transformerKey {
@ -248,14 +262,19 @@ NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString *
#pragma mark - Image Blending
@interface SDWebImageTintTransformer ()
@property (nonatomic, strong, nonnull) UIColor *tintColor;
@end
@implementation SDWebImageTintTransformer
- (instancetype)initWithColor:(UIColor *)tintColor {
self = [super init];
if (self) {
_tintColor = tintColor;
}
return self;
+ (instancetype)transformerWithColor:(UIColor *)tintColor {
SDWebImageTintTransformer *transformer = [SDWebImageTintTransformer new];
transformer.tintColor = tintColor;
return transformer;
}
- (NSString *)transformerKey {
@ -273,14 +292,19 @@ NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString *
#pragma mark - Image Effect
@interface SDWebImageBlurTransformer ()
@property (nonatomic, assign) CGFloat blurRadius;
@end
@implementation SDWebImageBlurTransformer
- (instancetype)initWithRadius:(CGFloat)blurRadius {
self = [super init];
if (self) {
_blurRadius = blurRadius;
}
return self;
+ (instancetype)transformerWithRadius:(CGFloat)blurRadius {
SDWebImageBlurTransformer *transformer = [SDWebImageBlurTransformer new];
transformer.blurRadius = blurRadius;
return transformer;
}
- (NSString *)transformerKey {
@ -297,14 +321,19 @@ NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString *
@end
#if SD_UIKIT || SD_MAC
@interface SDWebImageFilterTransformer ()
@property (nonatomic, strong, nonnull) CIFilter *filter;
@end
@implementation SDWebImageFilterTransformer
- (instancetype)initWithFilter:(CIFilter *)filter {
self = [super init];
if (self) {
_filter = filter;
}
return self;
+ (instancetype)transformerWithFilter:(CIFilter *)filter {
SDWebImageFilterTransformer *transformer = [SDWebImageFilterTransformer new];
transformer.filter = filter;
return transformer;
}
- (NSString *)transformerKey {

View File

@ -35,10 +35,10 @@ typedef NS_OPTIONS(NSUInteger, SDRectCorner) {
#pragma mark - Image Geometry
/**
Returns a new image which is scaled from this image.
The image content will be changed with the scale mode.
Returns a new image which is resized from this image.
You can specify a larger or smaller size than the image size. The image content will be changed with the scale mode.
@param size The new size to be scaled, values should be positive.
@param size The new size to be resized, values should be positive.
@param scaleMode The scale mode for image content.
@return The new image with the given size.
*/

View File

@ -12,6 +12,8 @@
2D7AF0601F329763000083C2 /* SDTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D7AF05F1F329763000083C2 /* SDTestCase.m */; };
321259EC1F39E3240096FE0E /* TestImageStatic.webp in Resources */ = {isa = PBXBuildFile; fileRef = 321259EB1F39E3240096FE0E /* TestImageStatic.webp */; };
321259EE1F39E4110096FE0E /* TestImageAnimated.webp in Resources */ = {isa = PBXBuildFile; fileRef = 321259ED1F39E4110096FE0E /* TestImageAnimated.webp */; };
3254C32020641077008D1022 /* SDWebImageTransformerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3254C31F20641077008D1022 /* SDWebImageTransformerTests.m */; };
3254C32120641077008D1022 /* SDWebImageTransformerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3254C31F20641077008D1022 /* SDWebImageTransformerTests.m */; };
3264FF2F205D42CB00F6BD48 /* SDWebImageTestTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */; };
3264FF30205D42CB00F6BD48 /* SDWebImageTestTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */; };
32B99E8B203AF8690017FD66 /* SDCategoriesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 32B99E8A203AF8690017FD66 /* SDCategoriesTests.m */; };
@ -58,6 +60,7 @@
2D7AF05F1F329763000083C2 /* SDTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDTestCase.m; sourceTree = "<group>"; };
321259EB1F39E3240096FE0E /* TestImageStatic.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = TestImageStatic.webp; sourceTree = "<group>"; };
321259ED1F39E4110096FE0E /* TestImageAnimated.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = TestImageAnimated.webp; sourceTree = "<group>"; };
3254C31F20641077008D1022 /* SDWebImageTransformerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageTransformerTests.m; sourceTree = "<group>"; };
3264FF2D205D42CB00F6BD48 /* SDWebImageTestTransformer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageTestTransformer.h; sourceTree = "<group>"; };
3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageTestTransformer.m; sourceTree = "<group>"; };
32B99E8A203AF8690017FD66 /* SDCategoriesTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDCategoriesTests.m; sourceTree = "<group>"; };
@ -189,6 +192,7 @@
1E3C51E819B46E370092B5E6 /* SDWebImageDownloaderTests.m */,
433BBBB41D7EF5C00086B6E9 /* SDWebImageDecoderTests.m */,
4369C1D01D97F80F007E863A /* SDWebImagePrefetcherTests.m */,
3254C31F20641077008D1022 /* SDWebImageTransformerTests.m */,
4369C2731D9804B1007E863A /* SDWebCacheCategoriesTests.m */,
32B99E8A203AF8690017FD66 /* SDCategoriesTests.m */,
37D122861EC48B5E00D98CEB /* SDMockFileManager.h */,
@ -445,6 +449,7 @@
buildActionMask = 2147483647;
files = (
32B99EAC203B36650017FD66 /* SDWebImageDownloaderTests.m in Sources */,
3254C32120641077008D1022 /* SDWebImageTransformerTests.m in Sources */,
32B99E9C203B2EE40017FD66 /* SDCategoriesTests.m in Sources */,
32B99EAA203B365F0017FD66 /* SDImageCacheTests.m in Sources */,
32B99EAD203B36690017FD66 /* SDWebImagePrefetcherTests.m in Sources */,
@ -463,6 +468,7 @@
buildActionMask = 2147483647;
files = (
32E6F0321F3A1B4700A945E6 /* SDWebImageTestDecoder.m in Sources */,
3254C32020641077008D1022 /* SDWebImageTransformerTests.m in Sources */,
1E3C51E919B46E370092B5E6 /* SDWebImageDownloaderTests.m in Sources */,
37D122881EC48B5E00D98CEB /* SDMockFileManager.m in Sources */,
4369C2741D9804B1007E863A /* SDWebCacheCategoriesTests.m in Sources */,

View File

@ -15,20 +15,9 @@
#import <SDWebImage/UIImage+MultiFormat.h>
#import <SDWebImage/UIImage+GIF.h>
#import <SDWebImage/UIImage+WebP.h>
#import <SDWebImage/UIImage+Transform.h>
#import <CoreImage/CoreImage.h>
// Internal header
@interface UIColor (HexString)
@property (nonatomic, copy, readonly, nonnull) NSString *sd_hexString;
@end
@interface SDCategoriesTests : SDTestCase
@property (nonatomic, strong) UIImage *testImage;
@end
@implementation SDCategoriesTests
@ -76,110 +65,8 @@
expect(image).notTo.beNil();
}
// UIImage+Transform test is hard to write because it's more about visual effect. Current it's tied to the `TestImage.png`, please keep that image or write new test with new image
- (void)test05UIImageTransformResize {
CGSize size = CGSizeMake(200, 100);
UIImage *resizedImage = [self.testImage sd_resizedImageWithSize:size scaleMode:SDImageScaleModeFill];
expect(CGSizeEqualToSize(resizedImage.size, size)).beTruthy();
}
- (void)test06UIImageTransformCrop {
CGRect rect = CGRectMake(50, 50, 200, 200);
UIImage *croppedImage = [self.testImage sd_croppedImageWithRect:rect];
expect(CGSizeEqualToSize(croppedImage.size, CGSizeMake(200, 200))).beTruthy();
UIColor *startColor = [croppedImage sd_colorAtPoint:CGPointZero];
expect([startColor.sd_hexString isEqualToString:[UIColor clearColor].sd_hexString]).beTruthy();
}
- (void)test07UIImageTransformRoundedCorner {
CGFloat radius = 50;
#if SD_UIKIT
SDRectCorner corners = UIRectCornerAllCorners;
#else
SDRectCorner corners = SDRectCornerAllCorners;
#endif
CGFloat borderWidth = 1;
UIColor *borderCoder = [UIColor blackColor];
UIImage *roundedCornerImage = [self.testImage sd_roundedCornerImageWithRadius:radius corners:corners borderWidth:borderWidth borderColor:borderCoder];
expect(CGSizeEqualToSize(roundedCornerImage.size, CGSizeMake(300, 300))).beTruthy();
UIColor *startColor = [roundedCornerImage sd_colorAtPoint:CGPointZero];
expect([startColor.sd_hexString isEqualToString:[UIColor clearColor].sd_hexString]).beTruthy();
// Check the left center pixel, should be border :)
UIColor *checkBorderColor = [roundedCornerImage sd_colorAtPoint:CGPointMake(1, 150)];
expect([checkBorderColor.sd_hexString isEqualToString:borderCoder.sd_hexString]).beTruthy();
}
- (void)test08UIImageTransformRotate {
CGFloat angle = M_PI_4;
UIImage *rotatedImage = [self.testImage sd_rotatedImageWithAngle:angle fitSize:NO];
// Not fit size and no change
expect(CGSizeEqualToSize(rotatedImage.size, self.testImage.size)).beTruthy();
// Fit size, may change size
rotatedImage = [self.testImage sd_rotatedImageWithAngle:angle fitSize:YES];
CGSize rotatedSize = CGSizeMake(floor(300 * 1.414), floor(300 * 1.414)); // 45º, square length * sqrt(2)
expect(CGSizeEqualToSize(rotatedImage.size, rotatedSize)).beTruthy();
rotatedImage = [self.testImage sd_rotatedImageWithAngle:angle fitSize:NO];
}
- (void)test09UIImageTransformFlip {
BOOL horizontal = YES;
BOOL vertical = YES;
UIImage *flippedImage = [self.testImage sd_flippedImageWithHorizontal:horizontal vertical:vertical];
expect(CGSizeEqualToSize(flippedImage.size, self.testImage.size)).beTruthy();
// Test pixel colors method here
UIColor *checkColor = [flippedImage sd_colorAtPoint:CGPointMake(75, 75)];
expect(checkColor);
NSArray<UIColor *> *checkColors = [flippedImage sd_colorsWithRect:CGRectMake(75, 75, 10, 10)]; // Rect are all same color
expect(checkColors.count).to.equal(10 * 10);
for (UIColor *color in checkColors) {
expect([color isEqual:checkColor]).to.beTruthy();
}
}
- (void)test10UIImageTransformTint {
UIColor *tintColor = [UIColor blackColor];
UIImage *tintedImage = [self.testImage sd_tintedImageWithColor:tintColor];
expect(CGSizeEqualToSize(tintedImage.size, self.testImage.size)).beTruthy();
// Check center color, should keep clear
UIColor *centerColor = [tintedImage sd_colorAtPoint:CGPointMake(150, 150)];
expect([centerColor.sd_hexString isEqualToString:[UIColor clearColor].sd_hexString]);
// Check left color, should be tinted
UIColor *leftColor = [tintedImage sd_colorAtPoint:CGPointMake(80, 150)];
expect([leftColor.sd_hexString isEqualToString:tintColor.sd_hexString]);
}
- (void)test11UIImageTransformBlur {
CGFloat radius = 50;
UIImage *blurredImage = [self.testImage sd_blurredImageWithRadius:radius];
expect(CGSizeEqualToSize(blurredImage.size, self.testImage.size)).beTruthy();
// Check left color, should be blurred
UIColor *leftColor = [blurredImage sd_colorAtPoint:CGPointMake(80, 150)];
// Hard-code from the output
UIColor *expectedColor = [UIColor colorWithRed:0.431373 green:0.101961 blue:0.0901961 alpha:0.729412];
expect([leftColor.sd_hexString isEqualToString:expectedColor.sd_hexString]);
}
- (void)test12UIImageTransformFilter {
// Invert color filter
CIFilter *filter = [CIFilter filterWithName:@"CIColorInvert"];
UIImage *filteredImage = [self.testImage sd_filteredImageWithFilter:filter];
expect(CGSizeEqualToSize(filteredImage.size, self.testImage.size)).beTruthy();
// Check left color, should be inverted
UIColor *leftColor = [filteredImage sd_colorAtPoint:CGPointMake(80, 150)];
// Hard-code from the output
UIColor *expectedColor = [UIColor colorWithRed:0.85098 green:0.992157 blue:0.992157 alpha:1];
expect([leftColor.sd_hexString isEqualToString:expectedColor.sd_hexString]);
}
#pragma mark - Helper
- (UIImage *)testImage {
if (!_testImage) {
_testImage = [[UIImage alloc] initWithContentsOfFile:[self testPNGPath]];
}
return _testImage;
}
- (NSString *)testJPEGPath {
NSBundle *testBundle = [NSBundle bundleForClass:[self class]];
return [testBundle pathForResource:@"TestImage" ofType:@"jpg"];
@ -195,9 +82,4 @@
return [testBundle pathForResource:@"TestImageStatic" ofType:@"webp"];
}
- (NSString *)testPNGPath {
NSBundle *testBundle = [NSBundle bundleForClass:[self class]];
return [testBundle pathForResource:@"TestImage" ofType:@"png"];
}
@end

View File

@ -0,0 +1,168 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
* (c) Matt Galloway
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDTestCase.h"
#import <SDWebImage/UIImage+Transform.h>
#import <CoreImage/CoreImage.h>
#import <SDWebImage/SDWebImageTransformer.h>
// Internal header
@interface UIColor (HexString)
@property (nonatomic, copy, readonly, nonnull) NSString *sd_hexString;
@end
@interface SDWebImageTransformerTests : SDTestCase
@property (nonatomic, strong) UIImage *testImage;
@end
@implementation SDWebImageTransformerTests
#pragma mark - UIImage+Transform
// UIImage+Transform test is hard to write because it's more about visual effect. Current it's tied to the `TestImage.png`, please keep that image or write new test with new image
- (void)test01UIImageTransformResize {
CGSize scaleDownSize = CGSizeMake(200, 100);
UIImage *scaledDownImage = [self.testImage sd_resizedImageWithSize:scaleDownSize scaleMode:SDImageScaleModeFill];
expect(CGSizeEqualToSize(scaledDownImage.size, scaleDownSize)).beTruthy();
CGSize scaleUpSize = CGSizeMake(2000, 1000);
UIImage *scaledUpImage = [self.testImage sd_resizedImageWithSize:scaleUpSize scaleMode:SDImageScaleModeAspectFit];
expect(CGSizeEqualToSize(scaledUpImage.size, scaleUpSize)).beTruthy();
}
- (void)test02UIImageTransformCrop {
CGRect rect = CGRectMake(50, 50, 200, 200);
UIImage *croppedImage = [self.testImage sd_croppedImageWithRect:rect];
expect(CGSizeEqualToSize(croppedImage.size, CGSizeMake(200, 200))).beTruthy();
UIColor *startColor = [croppedImage sd_colorAtPoint:CGPointZero];
expect([startColor.sd_hexString isEqualToString:[UIColor clearColor].sd_hexString]).beTruthy();
}
- (void)test03UIImageTransformRoundedCorner {
CGFloat radius = 50;
#if SD_UIKIT
SDRectCorner corners = UIRectCornerAllCorners;
#else
SDRectCorner corners = SDRectCornerAllCorners;
#endif
CGFloat borderWidth = 1;
UIColor *borderColor = [UIColor blackColor];
UIImage *roundedCornerImage = [self.testImage sd_roundedCornerImageWithRadius:radius corners:corners borderWidth:borderWidth borderColor:borderColor];
expect(CGSizeEqualToSize(roundedCornerImage.size, CGSizeMake(300, 300))).beTruthy();
UIColor *startColor = [roundedCornerImage sd_colorAtPoint:CGPointZero];
expect([startColor.sd_hexString isEqualToString:[UIColor clearColor].sd_hexString]).beTruthy();
// Check the left center pixel, should be border :)
UIColor *checkBorderColor = [roundedCornerImage sd_colorAtPoint:CGPointMake(1, 150)];
expect([checkBorderColor.sd_hexString isEqualToString:borderColor.sd_hexString]).beTruthy();
}
- (void)test04UIImageTransformRotate {
CGFloat angle = M_PI_4;
UIImage *rotatedImage = [self.testImage sd_rotatedImageWithAngle:angle fitSize:NO];
// Not fit size and no change
expect(CGSizeEqualToSize(rotatedImage.size, self.testImage.size)).beTruthy();
// Fit size, may change size
rotatedImage = [self.testImage sd_rotatedImageWithAngle:angle fitSize:YES];
CGSize rotatedSize = CGSizeMake(floor(300 * 1.414), floor(300 * 1.414)); // 45º, square length * sqrt(2)
expect(CGSizeEqualToSize(rotatedImage.size, rotatedSize)).beTruthy();
rotatedImage = [self.testImage sd_rotatedImageWithAngle:angle fitSize:NO];
}
- (void)test05UIImageTransformFlip {
BOOL horizontal = YES;
BOOL vertical = YES;
UIImage *flippedImage = [self.testImage sd_flippedImageWithHorizontal:horizontal vertical:vertical];
expect(CGSizeEqualToSize(flippedImage.size, self.testImage.size)).beTruthy();
// Test pixel colors method here
UIColor *checkColor = [flippedImage sd_colorAtPoint:CGPointMake(75, 75)];
expect(checkColor);
NSArray<UIColor *> *checkColors = [flippedImage sd_colorsWithRect:CGRectMake(75, 75, 10, 10)]; // Rect are all same color
expect(checkColors.count).to.equal(10 * 10);
for (UIColor *color in checkColors) {
expect([color isEqual:checkColor]).to.beTruthy();
}
}
- (void)test06UIImageTransformTint {
UIColor *tintColor = [UIColor blackColor];
UIImage *tintedImage = [self.testImage sd_tintedImageWithColor:tintColor];
expect(CGSizeEqualToSize(tintedImage.size, self.testImage.size)).beTruthy();
// Check center color, should keep clear
UIColor *centerColor = [tintedImage sd_colorAtPoint:CGPointMake(150, 150)];
expect([centerColor.sd_hexString isEqualToString:[UIColor clearColor].sd_hexString]);
// Check left color, should be tinted
UIColor *leftColor = [tintedImage sd_colorAtPoint:CGPointMake(80, 150)];
expect([leftColor.sd_hexString isEqualToString:tintColor.sd_hexString]);
}
- (void)test07UIImageTransformBlur {
CGFloat radius = 50;
UIImage *blurredImage = [self.testImage sd_blurredImageWithRadius:radius];
expect(CGSizeEqualToSize(blurredImage.size, self.testImage.size)).beTruthy();
// Check left color, should be blurred
UIColor *leftColor = [blurredImage sd_colorAtPoint:CGPointMake(80, 150)];
// Hard-code from the output
UIColor *expectedColor = [UIColor colorWithRed:0.431373 green:0.101961 blue:0.0901961 alpha:0.729412];
expect([leftColor.sd_hexString isEqualToString:expectedColor.sd_hexString]);
}
- (void)test08UIImageTransformFilter {
// Invert color filter
CIFilter *filter = [CIFilter filterWithName:@"CIColorInvert"];
UIImage *filteredImage = [self.testImage sd_filteredImageWithFilter:filter];
expect(CGSizeEqualToSize(filteredImage.size, self.testImage.size)).beTruthy();
// Check left color, should be inverted
UIColor *leftColor = [filteredImage sd_colorAtPoint:CGPointMake(80, 150)];
// Hard-code from the output
UIColor *expectedColor = [UIColor colorWithRed:0.85098 green:0.992157 blue:0.992157 alpha:1];
expect([leftColor.sd_hexString isEqualToString:expectedColor.sd_hexString]);
}
#pragma mark - SDWebImageTransformer
- (void)test09ImagePipelineTransformer {
CGSize size = CGSizeMake(100, 100);
SDImageScaleMode scaleMode = SDImageScaleModeAspectFill;
CGFloat angle = M_PI_4;
BOOL fitSize = NO;
CGFloat radius = 50;
#if SD_UIKIT
SDRectCorner corners = UIRectCornerAllCorners;
#else
SDRectCorner corners = SDRectCornerAllCorners;
#endif
CGFloat borderWidth = 1;
UIColor *borderCoder = [UIColor blackColor];
SDWebImageResizingTransformer *transformer1 = [SDWebImageResizingTransformer transformerWithSize:size scaleMode:scaleMode];
SDWebImageRotationTransformer *transformer2 = [SDWebImageRotationTransformer transformerWithAngle:angle fitSize:fitSize];
SDWebImageRoundCornerTransformer *transformer3 = [SDWebImageRoundCornerTransformer transformerWithRadius:radius corners:corners borderWidth:borderWidth borderColor:borderCoder];
SDWebImagePipelineTransformer *pipelineTransformer = [SDWebImagePipelineTransformer transformerWithTransformers:@[transformer1, transformer2, transformer3]];
UIImage *transformedImage = [pipelineTransformer transformedImageWithImage:self.testImage forKey:@"Test"];
expect(CGSizeEqualToSize(transformedImage.size, size)).beTruthy();
}
#pragma mark - Helper
- (UIImage *)testImage {
if (!_testImage) {
_testImage = [[UIImage alloc] initWithContentsOfFile:[self testPNGPath]];
}
return _testImage;
}
- (NSString *)testPNGPath {
NSBundle *testBundle = [NSBundle bundleForClass:[self class]];
return [testBundle pathForResource:@"TestImage" ofType:@"png"];
}
@end