Skip to content

Commit b64e80b

Browse files
committed
feat: Allows user to directly customize preserveImageMetadata for our built-in transformers
1 parent c085d53 commit b64e80b

File tree

3 files changed

+59
-12
lines changed

3 files changed

+59
-12
lines changed

SDWebImage/Core/SDImageTransformer.h

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ FOUNDATION_EXPORT NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullab
4040
@optional
4141

4242
/**
43-
Defaults to YES.
43+
Defaults to YES if you don't implements this method.
4444
We keep some metadata like Image Format (`sd_imageFormat`)/ Animated Loop Count (`sd_imageLoopCount`) via associated object on UIImage instance.
4545
When transformer generate a new UIImage instance, in most cases you still want to keep these information. So this is what for during the image loading pipeline.
4646
If the value is YES, we will keep and override the metadata **After you generate the UIImage**
@@ -74,8 +74,9 @@ FOUNDATION_EXPORT NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullab
7474
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.
7575
@note Because transformers are lightweight, if you want to append or arrange transformers, create another pipeline transformer instead. This class is considered as immutable.
7676
*/
77-
@interface SDImagePipelineTransformer : NSObject <SDImageTransformer>
78-
77+
@interface SDImagePipelineTransformer : NSObject<SDImageTransformer>
78+
/// For pipeline transformer, this property is readonly and always return NO. We handle each transformer's choice inside implementation
79+
@property (nonatomic, assign, readonly) BOOL preserveImageMetadata;
7980
/**
8081
All transformers in pipeline
8182
*/
@@ -88,14 +89,21 @@ FOUNDATION_EXPORT NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullab
8889

8990
@end
9091

92+
#pragma mark - Base
93+
/// This is the base class for our built-in concrete transformers. You should not use this class directlly, use cconcrete subclass (like `SDImageRoundCornerTransformer`) instead.
94+
@interface SDImageBaseTransformer : NSObject<SDImageTransformer>
95+
/// For concrete transformer, this property is readwrite and defaults to YES. You can choose whether to preserve image metadata **After you generate the UIImage**
96+
@property (nonatomic, assign, readwrite) BOOL preserveImageMetadata;
97+
@end
98+
9199
// 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.
92100
// Because transformers are lightweight, these class are considered as immutable.
93101
#pragma mark - Image Geometry
94102

95103
/**
96104
Image round corner transformer
97105
*/
98-
@interface SDImageRoundCornerTransformer: NSObject <SDImageTransformer>
106+
@interface SDImageRoundCornerTransformer: SDImageBaseTransformer
99107

100108
/**
101109
The radius of each corner oval. Values larger than half the
@@ -133,7 +141,7 @@ FOUNDATION_EXPORT NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullab
133141
/**
134142
Image resizing transformer
135143
*/
136-
@interface SDImageResizingTransformer : NSObject <SDImageTransformer>
144+
@interface SDImageResizingTransformer : SDImageBaseTransformer
137145

138146
/**
139147
The new size to be resized, values should be positive.
@@ -155,7 +163,7 @@ FOUNDATION_EXPORT NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullab
155163
/**
156164
Image cropping transformer
157165
*/
158-
@interface SDImageCroppingTransformer : NSObject <SDImageTransformer>
166+
@interface SDImageCroppingTransformer : SDImageBaseTransformer
159167

160168
/**
161169
Image's inner rect.
@@ -172,7 +180,7 @@ FOUNDATION_EXPORT NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullab
172180
/**
173181
Image flipping transformer
174182
*/
175-
@interface SDImageFlippingTransformer : NSObject <SDImageTransformer>
183+
@interface SDImageFlippingTransformer : SDImageBaseTransformer
176184

177185
/**
178186
YES to flip the image horizontally. ⇋
@@ -194,7 +202,7 @@ FOUNDATION_EXPORT NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullab
194202
/**
195203
Image rotation transformer
196204
*/
197-
@interface SDImageRotationTransformer : NSObject <SDImageTransformer>
205+
@interface SDImageRotationTransformer : SDImageBaseTransformer
198206

199207
/**
200208
Rotated radians in counterclockwise.⟲
@@ -219,7 +227,7 @@ FOUNDATION_EXPORT NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullab
219227
/**
220228
Image tint color transformer
221229
*/
222-
@interface SDImageTintTransformer : NSObject <SDImageTransformer>
230+
@interface SDImageTintTransformer : SDImageBaseTransformer
223231

224232
/**
225233
The tint color.
@@ -241,7 +249,7 @@ FOUNDATION_EXPORT NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullab
241249
/**
242250
Image blur effect transformer
243251
*/
244-
@interface SDImageBlurTransformer : NSObject <SDImageTransformer>
252+
@interface SDImageBlurTransformer : SDImageBaseTransformer
245253

246254
/**
247255
The radius of the blur in points, 0 means no blur effect.
@@ -259,7 +267,7 @@ FOUNDATION_EXPORT NSString * _Nullable SDThumbnailedKeyForKey(NSString * _Nullab
259267
/**
260268
Core Image filter transformer
261269
*/
262-
@interface SDImageFilterTransformer: NSObject <SDImageTransformer>
270+
@interface SDImageFilterTransformer: SDImageBaseTransformer
263271

264272
/**
265273
The CIFilter to be applied to the image.

SDWebImage/Core/SDImageTransformer.m

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#import "SDImageTransformer.h"
1010
#import "UIColor+SDHexString.h"
11+
#import "SDAssociatedObject.h"
1112
#if SD_UIKIT || SD_MAC
1213
#import <CoreImage/CoreImage.h>
1314
#endif
@@ -73,19 +74,56 @@ + (NSString *)cacheKeyForTransformers:(NSArray<id<SDImageTransformer>> *)transfo
7374
return [cacheKeys componentsJoinedByString:SDImageTransformerKeySeparator];
7475
}
7576

77+
- (BOOL)preserveImageMetadata {
78+
return NO; // We handle this logic inside `transformedImageWithImage` below
79+
}
80+
7681
- (UIImage *)transformedImageWithImage:(UIImage *)image forKey:(NSString *)key {
7782
if (!image) {
7883
return nil;
7984
}
8085
UIImage *transformedImage = image;
8186
for (id<SDImageTransformer> transformer in self.transformers) {
82-
transformedImage = [transformer transformedImageWithImage:transformedImage forKey:key];
87+
UIImage *newImage = [transformer transformedImageWithImage:transformedImage forKey:key];
88+
// Handle each transformer's preserveImageMetadata choice
89+
BOOL preserveImageMetadata = YES;
90+
if ([transformer respondsToSelector:@selector(preserveImageMetadata)]) {
91+
preserveImageMetadata = transformer.preserveImageMetadata;
92+
}
93+
if (preserveImageMetadata) {
94+
SDImageCopyAssociatedObject(transformedImage, newImage);
95+
}
96+
transformedImage = newImage;
8397
}
8498
return transformedImage;
8599
}
86100

87101
@end
88102

103+
@implementation SDImageBaseTransformer
104+
105+
- (instancetype)init {
106+
self = [super init];
107+
if (self) {
108+
_preserveImageMetadata = YES;
109+
}
110+
return self;
111+
}
112+
113+
- (NSString *)transformerKey {
114+
@throw [NSException exceptionWithName:NSInternalInconsistencyException
115+
reason:[NSString stringWithFormat:@"For `SDImageBaseTransformer` subclass, you must override %@ method", NSStringFromSelector(_cmd)]
116+
userInfo:nil];
117+
}
118+
119+
- (nullable UIImage *)transformedImageWithImage:(nonnull UIImage *)image forKey:(nonnull NSString *)key {
120+
@throw [NSException exceptionWithName:NSInternalInconsistencyException
121+
reason:[NSString stringWithFormat:@"For `SDImageBaseTransformer` subclass, you must override %@ method", NSStringFromSelector(_cmd)]
122+
userInfo:nil];
123+
}
124+
125+
@end
126+
89127
@interface SDImageRoundCornerTransformer ()
90128

91129
@property (nonatomic, assign) CGFloat cornerRadius;

SDWebImage/Core/SDWebImageManager.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ - (void)callTransformProcessForOperation:(nonnull SDWebImageCombinedOperation *)
512512
if (transformedImage) {
513513
// We need keep some metadata from the full size image when needed
514514
// Because most of our transformer does not care about these information
515+
// So we add a **post-process** logic here, not a good design :(
515516
BOOL preserveImageMetadata = YES;
516517
if ([transformer respondsToSelector:@selector(preserveImageMetadata)]) {
517518
preserveImageMetadata = transformer.preserveImageMetadata;

0 commit comments

Comments
 (0)