23
23
#import " RCTImageUtils.h"
24
24
#endif
25
25
26
+ #define DEFAULT_DISPLAY_SIZE 0
26
27
#define DEFAULT_COMPRESSION_QUALITY 0.9
27
28
#define DEFAULT_RESIZE_MODE " cover"
28
29
30
+ struct Params {
31
+ public:
32
+ CGPoint offset;
33
+ CGSize size;
34
+ CGSize displaySize;
35
+ RCTResizeMode resizeMode;
36
+ CGFloat quality;
37
+ NSString *format;
38
+ };
39
+
29
40
@implementation RNCImageEditor
30
41
31
42
RCT_EXPORT_MODULE ()
32
43
33
44
@synthesize bridge = _bridge;
34
45
46
+ - (Params)adaptParamsWithFormat : (id )format
47
+ width : (id )width
48
+ height : (id )height
49
+ offsetX : (id )offsetX
50
+ offsetY : (id )offsetY
51
+ resizeMode : (id )resizeMode
52
+ displayWidth : (id )displayWidth
53
+ displayHeight : (id )displayHeight
54
+ quality : (id )quality
55
+ {
56
+ return Params{
57
+ .offset = {[RCTConvert double: offsetX], [RCTConvert double: offsetY]},
58
+ .size = {[RCTConvert double: width], [RCTConvert double: height]},
59
+ .displaySize = {[RCTConvert double: displayWidth], [RCTConvert double: displayHeight]},
60
+ .resizeMode = [RCTConvert RCTResizeMode: resizeMode ?: @(DEFAULT_RESIZE_MODE)],
61
+ .quality = [RCTConvert CGFloat: quality],
62
+ .format = [RCTConvert NSString: format]
63
+ };
64
+ }
65
+
35
66
/* *
36
67
* Crops an image and saves the result to temporary file. Consider using
37
68
* CameraRoll API or other third-party module to save it in gallery.
@@ -49,71 +80,60 @@ - (void) cropImage:(NSString *)uri
49
80
resolve : (RCTPromiseResolveBlock)resolve
50
81
reject : (RCTPromiseRejectBlock)reject
51
82
{
52
- NSString *format = data.format ();
53
- CGSize size = [RCTConvert CGSize: @{ @" width" : @(data.size ().width ()), @" height" : @(data.size ().height ()) }];
54
- CGPoint offset = [RCTConvert CGPoint: @{ @" x" : @(data.offset ().x ()), @" y" : @(data.offset ().y ()) }];
55
- CGSize targetSize = size;
56
- CGSize displaySize = CGSizeZero;
57
- BOOL hasDisplaySizeValue = data.displaySize ().has_value ();
58
- if (hasDisplaySizeValue) {
59
- JS::NativeRNCImageEditor::SpecCropImageCropDataDisplaySize rawDisplaySize = *data.displaySize (); // Extract the value from the optional
60
- // in pixels
61
- displaySize = [RCTConvert CGSize: @{ @" width" : @(rawDisplaySize.width ()), @" height" : @(rawDisplaySize.height ()) }];
62
- }
63
- RCTResizeMode resizeMode = [RCTConvert RCTResizeMode: data.resizeMode () ?: @(DEFAULT_RESIZE_MODE)];
64
- NSURLRequest *imageRequest = [NSURLRequest requestWithURL: [NSURL URLWithString: uri]];
65
- CGFloat compressionQuality = DEFAULT_COMPRESSION_QUALITY;
66
- if (data.quality ().has_value ()) {
67
- compressionQuality = *data.quality ();
68
- }
83
+ NSURLRequest *imageRequest = [NSURLRequest requestWithURL: [NSURL URLWithString: uri]];
84
+ auto params = [self adaptParamsWithFormat: data.format ()
85
+ width: @(data.size ().width ())
86
+ height: @(data.size ().height ())
87
+ offsetX: @(data.offset ().x ())
88
+ offsetY: @(data.offset ().y ())
89
+ resizeMode: data.resizeMode ()
90
+ displayWidth: @(data.displaySize ().has_value () ? data.displaySize ()->width () : DEFAULT_DISPLAY_SIZE)
91
+ displayHeight: @(data.displaySize ().has_value () ? data.displaySize ()->height () : DEFAULT_DISPLAY_SIZE)
92
+ quality: @(data.quality ().has_value () ? *data.quality () : DEFAULT_COMPRESSION_QUALITY)];
69
93
#else
70
94
RCT_EXPORT_METHOD (cropImage:(NSURLRequest *)imageRequest
71
95
cropData:(NSDictionary *)cropData
72
96
resolve:(RCTPromiseResolveBlock)resolve
73
97
reject:(RCTPromiseRejectBlock)reject)
74
98
{
75
- NSString *format = cropData[@" format" ];
76
- CGSize size = [RCTConvert CGSize: cropData[@" size" ]];
77
- CGPoint offset = [RCTConvert CGPoint: cropData[@" offset" ]];
78
- RCTResizeMode resizeMode = [RCTConvert RCTResizeMode: cropData[@" resizeMode" ] ?: @(DEFAULT_RESIZE_MODE)];
79
- CGSize displaySize = CGSizeZero;
80
- BOOL hasDisplaySizeValue = cropData[@" displaySize" ];
81
- if (hasDisplaySizeValue){
82
- displaySize = [RCTConvert CGSize: cropData[@" displaySize" ]];
83
- }
84
- CGFloat compressionQuality = DEFAULT_COMPRESSION_QUALITY;
85
- if (cropData[@" quality" ]){
86
- compressionQuality = [RCTConvert CGFloat: cropData[@" quality" ]];
87
- }
99
+ auto params = [self adaptParamsWithFormat: cropData[@" format" ]
100
+ width: cropData[@" size" ][@" width" ]
101
+ height: cropData[@" size" ][@" height" ]
102
+ offsetX: cropData[@" offset" ][@" x" ]
103
+ offsetY: cropData[@" offset" ][@" y" ]
104
+ resizeMode: cropData[@" resizeMode" ]
105
+ displayWidth: cropData[@" displaySize" ] ? cropData[@" displaySize" ][@" width" ] : @(DEFAULT_DISPLAY_SIZE)
106
+ displayHeight: cropData[@" displaySize" ] ? cropData[@" displaySize" ][@" height" ] : @(DEFAULT_DISPLAY_SIZE)
107
+ quality: cropData[@" quality" ] ? cropData[@" quality" ] : @(DEFAULT_COMPRESSION_QUALITY)];
108
+
88
109
#endif
89
- CGRect rect = {offset,size};
90
110
NSURL *url = [imageRequest URL ];
91
111
NSString *urlPath = [url path ];
92
112
NSString *extension = [urlPath pathExtension ];
93
- if ([format isEqualToString: @" png" ] || [format isEqualToString: @" jpeg" ]){
94
- extension = format;
113
+ if ([params. format isEqualToString: @" png" ] || [params. format isEqualToString: @" jpeg" ]){
114
+ extension = params. format ;
95
115
}
96
116
97
117
[[_bridge moduleForName: @" ImageLoader" lazilyLoadIfNecessary: YES ] loadImageWithURLRequest: imageRequest callback: ^(NSError *error, UIImage *image) {
98
118
if (error) {
99
119
reject (@(error.code ).stringValue , error.description , error);
100
120
return ;
101
121
}
102
- if (compressionQuality > 1 || compressionQuality < 0 ) {
122
+ if (params. quality > 1 || params. quality < 0 ) {
103
123
reject (RCTErrorUnspecified, @(" quality must be a number between 0 and 1" ), nil );
104
124
return ;
105
125
}
106
126
107
127
// Crop image
108
- CGSize targetSize = rect .size ;
109
- CGRect targetRect = {{-rect. origin .x , -rect. origin .y }, image.size };
128
+ CGSize targetSize = params .size ;
129
+ CGRect targetRect = {{-params. offset .x , -params. offset .y }, image.size };
110
130
CGAffineTransform transform = RCTTransformFromTargetRect (image.size , targetRect);
111
131
UIImage *croppedImage = RCTTransformImage (image, targetSize, image.scale , transform);
112
132
113
133
// Scale image
114
- if (hasDisplaySizeValue ) {
115
- targetSize = displaySize;
116
- targetRect = RCTTargetRect (croppedImage.size , targetSize, 1 , resizeMode);
134
+ if (params. displaySize . width != DEFAULT_DISPLAY_SIZE && params. displaySize . height != DEFAULT_DISPLAY_SIZE ) {
135
+ targetSize = params. displaySize ;
136
+ targetRect = RCTTargetRect (croppedImage.size , targetSize, 1 , params. resizeMode );
117
137
transform = RCTTransformFromTargetRect (croppedImage.size , targetRect);
118
138
croppedImage = RCTTransformImage (croppedImage, targetSize, image.scale , transform);
119
139
}
@@ -127,7 +147,7 @@ - (void) cropImage:(NSString *)uri
127
147
path = [RNCFileSystem generatePathInDirectory: [[RNCFileSystem cacheDirectoryPath ] stringByAppendingPathComponent: @" ReactNative_cropped_image_" ] withExtension: @" .png" ];
128
148
}
129
149
else {
130
- imageData = UIImageJPEGRepresentation (croppedImage, compressionQuality );
150
+ imageData = UIImageJPEGRepresentation (croppedImage, params. quality );
131
151
path = [RNCFileSystem generatePathInDirectory: [[RNCFileSystem cacheDirectoryPath ] stringByAppendingPathComponent: @" ReactNative_cropped_image_" ] withExtension: @" .jpg" ];
132
152
}
133
153
0 commit comments