123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- /*
- * This file is part of the SDWebImage package.
- * (c) Olivier Poitrey <rs@dailymotion.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- #import "SDImageTransformer.h"
- #import "UIColor+SDHexString.h"
- #if SD_UIKIT || SD_MAC
- #import <CoreImage/CoreImage.h>
- #endif
- // Separator for different transformerKey, for example, `image.png` |> flip(YES,NO) |> rotate(pi/4,YES) => 'image-SDImageFlippingTransformer(1,0)-SDImageRotationTransformer(0.78539816339,1).png'
- static NSString * const SDImageTransformerKeySeparator = @"-";
- NSString * _Nullable SDTransformedKeyForKey(NSString * _Nullable key, NSString * _Nonnull transformerKey) {
- if (!key || !transformerKey) {
- return nil;
- }
- // Find the file extension
- NSURL *keyURL = [NSURL URLWithString:key];
- NSString *ext = keyURL ? keyURL.pathExtension : key.pathExtension;
- if (ext.length > 0) {
- // For non-file URL
- if (keyURL && !keyURL.isFileURL) {
- // keep anything except path (like URL query)
- NSURLComponents *component = [NSURLComponents componentsWithURL:keyURL resolvingAgainstBaseURL:NO];
- component.path = [[[component.path.stringByDeletingPathExtension stringByAppendingString:SDImageTransformerKeySeparator] stringByAppendingString:transformerKey] stringByAppendingPathExtension:ext];
- return component.URL.absoluteString;
- } else {
- // file URL
- return [[[key.stringByDeletingPathExtension stringByAppendingString:SDImageTransformerKeySeparator] stringByAppendingString:transformerKey] stringByAppendingPathExtension:ext];
- }
- } else {
- return [[key stringByAppendingString:SDImageTransformerKeySeparator] stringByAppendingString:transformerKey];
- }
- }
- NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullable key, CGSize thumbnailPixelSize, BOOL preserveAspectRatio) {
- NSString *thumbnailKey = [NSString stringWithFormat:@"Thumbnail({%f,%f},%d)", thumbnailPixelSize.width, thumbnailPixelSize.height, preserveAspectRatio];
- return SDTransformedKeyForKey(key, thumbnailKey);
- }
- @interface SDImagePipelineTransformer ()
- @property (nonatomic, copy, readwrite, nonnull) NSArray<id<SDImageTransformer>> *transformers;
- @property (nonatomic, copy, readwrite) NSString *transformerKey;
- @end
- @implementation SDImagePipelineTransformer
- + (instancetype)transformerWithTransformers:(NSArray<id<SDImageTransformer>> *)transformers {
- SDImagePipelineTransformer *transformer = [SDImagePipelineTransformer new];
- transformer.transformers = transformers;
- transformer.transformerKey = [[self class] cacheKeyForTransformers:transformers];
-
- return transformer;
- }
- + (NSString *)cacheKeyForTransformers:(NSArray<id<SDImageTransformer>> *)transformers {
- if (transformers.count == 0) {
- return @"";
- }
- NSMutableArray<NSString *> *cacheKeys = [NSMutableArray arrayWithCapacity:transformers.count];
- [transformers enumerateObjectsUsingBlock:^(id<SDImageTransformer> _Nonnull transformer, NSUInteger idx, BOOL * _Nonnull stop) {
- NSString *cacheKey = transformer.transformerKey;
- [cacheKeys addObject:cacheKey];
- }];
-
- return [cacheKeys componentsJoinedByString:SDImageTransformerKeySeparator];
- }
- - (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {
- if (!image) {
- return nil;
- }
- UIImage *transformedImage = image;
- for (id<SDImageTransformer> transformer in self.transformers) {
- transformedImage = [transformer transformedImageWithImage:transformedImage forKey:key];
- }
- return transformedImage;
- }
- @end
- @interface SDImageRoundCornerTransformer ()
- @property (nonatomic, assign) CGFloat cornerRadius;
- @property (nonatomic, assign) SDRectCorner corners;
- @property (nonatomic, assign) CGFloat borderWidth;
- @property (nonatomic, strong, nullable) UIColor *borderColor;
- @end
- @implementation SDImageRoundCornerTransformer
- + (instancetype)transformerWithRadius:(CGFloat)cornerRadius corners:(SDRectCorner)corners borderWidth:(CGFloat)borderWidth borderColor:(UIColor *)borderColor {
- SDImageRoundCornerTransformer *transformer = [SDImageRoundCornerTransformer new];
- transformer.cornerRadius = cornerRadius;
- transformer.corners = corners;
- transformer.borderWidth = borderWidth;
- transformer.borderColor = borderColor;
-
- return transformer;
- }
- - (NSString *)transformerKey {
- return [NSString stringWithFormat:@"SDImageRoundCornerTransformer(%f,%lu,%f,%@)", self.cornerRadius, (unsigned long)self.corners, self.borderWidth, self.borderColor.sd_hexString];
- }
- - (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {
- if (!image) {
- return nil;
- }
- return [image sd_roundedCornerImageWithRadius:self.cornerRadius corners:self.corners borderWidth:self.borderWidth borderColor:self.borderColor];
- }
- @end
- @interface SDImageResizingTransformer ()
- @property (nonatomic, assign) CGSize size;
- @property (nonatomic, assign) SDImageScaleMode scaleMode;
- @end
- @implementation SDImageResizingTransformer
- + (instancetype)transformerWithSize:(CGSize)size scaleMode:(SDImageScaleMode)scaleMode {
- SDImageResizingTransformer *transformer = [SDImageResizingTransformer new];
- transformer.size = size;
- transformer.scaleMode = scaleMode;
-
- return transformer;
- }
- - (NSString *)transformerKey {
- CGSize size = self.size;
- return [NSString stringWithFormat:@"SDImageResizingTransformer({%f,%f},%lu)", size.width, size.height, (unsigned long)self.scaleMode];
- }
- - (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {
- if (!image) {
- return nil;
- }
- return [image sd_resizedImageWithSize:self.size scaleMode:self.scaleMode];
- }
- @end
- @interface SDImageCroppingTransformer ()
- @property (nonatomic, assign) CGRect rect;
- @end
- @implementation SDImageCroppingTransformer
- + (instancetype)transformerWithRect:(CGRect)rect {
- SDImageCroppingTransformer *transformer = [SDImageCroppingTransformer new];
- transformer.rect = rect;
-
- return transformer;
- }
- - (NSString *)transformerKey {
- CGRect rect = self.rect;
- return [NSString stringWithFormat:@"SDImageCroppingTransformer({%f,%f,%f,%f})", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height];
- }
- - (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {
- if (!image) {
- return nil;
- }
- return [image sd_croppedImageWithRect:self.rect];
- }
- @end
- @interface SDImageFlippingTransformer ()
- @property (nonatomic, assign) BOOL horizontal;
- @property (nonatomic, assign) BOOL vertical;
- @end
- @implementation SDImageFlippingTransformer
- + (instancetype)transformerWithHorizontal:(BOOL)horizontal vertical:(BOOL)vertical {
- SDImageFlippingTransformer *transformer = [SDImageFlippingTransformer new];
- transformer.horizontal = horizontal;
- transformer.vertical = vertical;
-
- return transformer;
- }
- - (NSString *)transformerKey {
- return [NSString stringWithFormat:@"SDImageFlippingTransformer(%d,%d)", self.horizontal, self.vertical];
- }
- - (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {
- if (!image) {
- return nil;
- }
- return [image sd_flippedImageWithHorizontal:self.horizontal vertical:self.vertical];
- }
- @end
- @interface SDImageRotationTransformer ()
- @property (nonatomic, assign) CGFloat angle;
- @property (nonatomic, assign) BOOL fitSize;
- @end
- @implementation SDImageRotationTransformer
- + (instancetype)transformerWithAngle:(CGFloat)angle fitSize:(BOOL)fitSize {
- SDImageRotationTransformer *transformer = [SDImageRotationTransformer new];
- transformer.angle = angle;
- transformer.fitSize = fitSize;
-
- return transformer;
- }
- - (NSString *)transformerKey {
- return [NSString stringWithFormat:@"SDImageRotationTransformer(%f,%d)", self.angle, self.fitSize];
- }
- - (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {
- if (!image) {
- return nil;
- }
- return [image sd_rotatedImageWithAngle:self.angle fitSize:self.fitSize];
- }
- @end
- #pragma mark - Image Blending
- @interface SDImageTintTransformer ()
- @property (nonatomic, strong, nonnull) UIColor *tintColor;
- @end
- @implementation SDImageTintTransformer
- + (instancetype)transformerWithColor:(UIColor *)tintColor {
- SDImageTintTransformer *transformer = [SDImageTintTransformer new];
- transformer.tintColor = tintColor;
-
- return transformer;
- }
- - (NSString *)transformerKey {
- return [NSString stringWithFormat:@"SDImageTintTransformer(%@)", self.tintColor.sd_hexString];
- }
- - (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {
- if (!image) {
- return nil;
- }
- return [image sd_tintedImageWithColor:self.tintColor];
- }
- @end
- #pragma mark - Image Effect
- @interface SDImageBlurTransformer ()
- @property (nonatomic, assign) CGFloat blurRadius;
- @end
- @implementation SDImageBlurTransformer
- + (instancetype)transformerWithRadius:(CGFloat)blurRadius {
- SDImageBlurTransformer *transformer = [SDImageBlurTransformer new];
- transformer.blurRadius = blurRadius;
-
- return transformer;
- }
- - (NSString *)transformerKey {
- return [NSString stringWithFormat:@"SDImageBlurTransformer(%f)", self.blurRadius];
- }
- - (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {
- if (!image) {
- return nil;
- }
- return [image sd_blurredImageWithRadius:self.blurRadius];
- }
- @end
- #if SD_UIKIT || SD_MAC
- @interface SDImageFilterTransformer ()
- @property (nonatomic, strong, nonnull) CIFilter *filter;
- @end
- @implementation SDImageFilterTransformer
- + (instancetype)transformerWithFilter:(CIFilter *)filter {
- SDImageFilterTransformer *transformer = [SDImageFilterTransformer new];
- transformer.filter = filter;
-
- return transformer;
- }
- - (NSString *)transformerKey {
- return [NSString stringWithFormat:@"SDImageFilterTransformer(%@)", self.filter.name];
- }
- - (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {
- if (!image) {
- return nil;
- }
- return [image sd_filteredImageWithFilter:self.filter];
- }
- @end
- #endif
|