stream-chat-react-native 9.0.0-beta.1 → 9.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/streamchatreactnative/StreamChatReactNative.java +0 -153
- package/android/src/main/java/com/streamchatreactnative/StreamChatReactNativeModule.java +2 -15
- package/android/src/oldarch/com/streamchatreactnative/StreamChatReactNative.java +1 -1
- package/ios/StreamChatReactNative.mm +16 -148
- package/package.json +2 -2
- package/src/handlers/compressImage.ts +0 -1
- package/src/native/NativeStreamChatReactNative.ts +0 -1
- package/src/native/index.tsx +0 -2
|
@@ -11,7 +11,6 @@ import android.net.Uri;
|
|
|
11
11
|
import android.os.Build;
|
|
12
12
|
import android.provider.MediaStore;
|
|
13
13
|
import android.util.Base64;
|
|
14
|
-
import android.util.Log;
|
|
15
14
|
|
|
16
15
|
import java.io.ByteArrayOutputStream;
|
|
17
16
|
import java.io.File;
|
|
@@ -33,108 +32,6 @@ public class StreamChatReactNative {
|
|
|
33
32
|
private final static String SCHEME_FILE = "file";
|
|
34
33
|
private final static String SCHEME_HTTP = "http";
|
|
35
34
|
private final static String SCHEME_HTTPS = "https";
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// List of known EXIF tags we will be copying.
|
|
39
|
-
// Orientation, width, height, and some others are ignored
|
|
40
|
-
// TODO: Find any missing tag that might be useful
|
|
41
|
-
private final static String[] EXIF_TO_COPY_ROTATED = new String[]
|
|
42
|
-
{
|
|
43
|
-
ExifInterface.TAG_APERTURE_VALUE,
|
|
44
|
-
ExifInterface.TAG_MAX_APERTURE_VALUE,
|
|
45
|
-
ExifInterface.TAG_METERING_MODE,
|
|
46
|
-
ExifInterface.TAG_ARTIST,
|
|
47
|
-
ExifInterface.TAG_BITS_PER_SAMPLE,
|
|
48
|
-
ExifInterface.TAG_COMPRESSION,
|
|
49
|
-
ExifInterface.TAG_BODY_SERIAL_NUMBER,
|
|
50
|
-
ExifInterface.TAG_BRIGHTNESS_VALUE,
|
|
51
|
-
ExifInterface.TAG_CONTRAST,
|
|
52
|
-
ExifInterface.TAG_CAMERA_OWNER_NAME,
|
|
53
|
-
ExifInterface.TAG_COLOR_SPACE,
|
|
54
|
-
ExifInterface.TAG_COPYRIGHT,
|
|
55
|
-
ExifInterface.TAG_DATETIME,
|
|
56
|
-
ExifInterface.TAG_DATETIME_DIGITIZED,
|
|
57
|
-
ExifInterface.TAG_DATETIME_ORIGINAL,
|
|
58
|
-
ExifInterface.TAG_DEVICE_SETTING_DESCRIPTION,
|
|
59
|
-
ExifInterface.TAG_DIGITAL_ZOOM_RATIO,
|
|
60
|
-
ExifInterface.TAG_EXIF_VERSION,
|
|
61
|
-
ExifInterface.TAG_EXPOSURE_BIAS_VALUE,
|
|
62
|
-
ExifInterface.TAG_EXPOSURE_INDEX,
|
|
63
|
-
ExifInterface.TAG_EXPOSURE_MODE,
|
|
64
|
-
ExifInterface.TAG_EXPOSURE_TIME,
|
|
65
|
-
ExifInterface.TAG_EXPOSURE_PROGRAM,
|
|
66
|
-
ExifInterface.TAG_FLASH,
|
|
67
|
-
ExifInterface.TAG_FLASH_ENERGY,
|
|
68
|
-
ExifInterface.TAG_FOCAL_LENGTH,
|
|
69
|
-
ExifInterface.TAG_FOCAL_LENGTH_IN_35MM_FILM,
|
|
70
|
-
ExifInterface.TAG_FOCAL_PLANE_RESOLUTION_UNIT,
|
|
71
|
-
ExifInterface.TAG_FOCAL_PLANE_X_RESOLUTION,
|
|
72
|
-
ExifInterface.TAG_FOCAL_PLANE_Y_RESOLUTION,
|
|
73
|
-
ExifInterface.TAG_PHOTOMETRIC_INTERPRETATION,
|
|
74
|
-
ExifInterface.TAG_PLANAR_CONFIGURATION,
|
|
75
|
-
ExifInterface.TAG_F_NUMBER,
|
|
76
|
-
ExifInterface.TAG_GAIN_CONTROL,
|
|
77
|
-
ExifInterface.TAG_GAMMA,
|
|
78
|
-
ExifInterface.TAG_GPS_ALTITUDE,
|
|
79
|
-
ExifInterface.TAG_GPS_ALTITUDE_REF,
|
|
80
|
-
ExifInterface.TAG_GPS_AREA_INFORMATION,
|
|
81
|
-
ExifInterface.TAG_GPS_DATESTAMP,
|
|
82
|
-
ExifInterface.TAG_GPS_DOP,
|
|
83
|
-
ExifInterface.TAG_GPS_LATITUDE,
|
|
84
|
-
ExifInterface.TAG_GPS_LATITUDE_REF,
|
|
85
|
-
ExifInterface.TAG_GPS_LONGITUDE,
|
|
86
|
-
ExifInterface.TAG_GPS_LONGITUDE_REF,
|
|
87
|
-
ExifInterface.TAG_GPS_STATUS,
|
|
88
|
-
ExifInterface.TAG_GPS_DEST_BEARING,
|
|
89
|
-
ExifInterface.TAG_GPS_DEST_BEARING_REF,
|
|
90
|
-
ExifInterface.TAG_GPS_DEST_DISTANCE,
|
|
91
|
-
ExifInterface.TAG_GPS_DEST_DISTANCE_REF,
|
|
92
|
-
ExifInterface.TAG_GPS_DEST_LATITUDE,
|
|
93
|
-
ExifInterface.TAG_GPS_DEST_LATITUDE_REF,
|
|
94
|
-
ExifInterface.TAG_GPS_DEST_LONGITUDE,
|
|
95
|
-
ExifInterface.TAG_GPS_DEST_LONGITUDE_REF,
|
|
96
|
-
ExifInterface.TAG_GPS_DIFFERENTIAL,
|
|
97
|
-
ExifInterface.TAG_GPS_IMG_DIRECTION,
|
|
98
|
-
ExifInterface.TAG_GPS_IMG_DIRECTION_REF,
|
|
99
|
-
ExifInterface.TAG_GPS_MAP_DATUM,
|
|
100
|
-
ExifInterface.TAG_GPS_MEASURE_MODE,
|
|
101
|
-
ExifInterface.TAG_GPS_PROCESSING_METHOD,
|
|
102
|
-
ExifInterface.TAG_GPS_SATELLITES,
|
|
103
|
-
ExifInterface.TAG_GPS_SPEED,
|
|
104
|
-
ExifInterface.TAG_GPS_SPEED_REF,
|
|
105
|
-
ExifInterface.TAG_GPS_STATUS,
|
|
106
|
-
ExifInterface.TAG_GPS_TIMESTAMP,
|
|
107
|
-
ExifInterface.TAG_GPS_TRACK,
|
|
108
|
-
ExifInterface.TAG_GPS_TRACK_REF,
|
|
109
|
-
ExifInterface.TAG_GPS_VERSION_ID,
|
|
110
|
-
ExifInterface.TAG_IMAGE_DESCRIPTION,
|
|
111
|
-
ExifInterface.TAG_IMAGE_UNIQUE_ID,
|
|
112
|
-
ExifInterface.TAG_ISO_SPEED,
|
|
113
|
-
ExifInterface.TAG_PHOTOGRAPHIC_SENSITIVITY,
|
|
114
|
-
ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT,
|
|
115
|
-
ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH,
|
|
116
|
-
ExifInterface.TAG_LENS_MAKE,
|
|
117
|
-
ExifInterface.TAG_LENS_MODEL,
|
|
118
|
-
ExifInterface.TAG_LENS_SERIAL_NUMBER,
|
|
119
|
-
ExifInterface.TAG_LENS_SPECIFICATION,
|
|
120
|
-
ExifInterface.TAG_LIGHT_SOURCE,
|
|
121
|
-
ExifInterface.TAG_MAKE,
|
|
122
|
-
ExifInterface.TAG_MAKER_NOTE,
|
|
123
|
-
ExifInterface.TAG_MODEL,
|
|
124
|
-
// ExifInterface.TAG_ORIENTATION, // removed
|
|
125
|
-
ExifInterface.TAG_SATURATION,
|
|
126
|
-
ExifInterface.TAG_SHARPNESS,
|
|
127
|
-
ExifInterface.TAG_SHUTTER_SPEED_VALUE,
|
|
128
|
-
ExifInterface.TAG_SOFTWARE,
|
|
129
|
-
ExifInterface.TAG_SUBJECT_DISTANCE,
|
|
130
|
-
ExifInterface.TAG_SUBJECT_DISTANCE_RANGE,
|
|
131
|
-
ExifInterface.TAG_SUBJECT_LOCATION,
|
|
132
|
-
ExifInterface.TAG_USER_COMMENT,
|
|
133
|
-
ExifInterface.TAG_WHITE_BALANCE
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
35
|
/**
|
|
139
36
|
* Resize the specified bitmap.
|
|
140
37
|
*/
|
|
@@ -263,55 +160,6 @@ public class StreamChatReactNative {
|
|
|
263
160
|
return file;
|
|
264
161
|
}
|
|
265
162
|
|
|
266
|
-
/**
|
|
267
|
-
* Attempts to copy exif info from one file to another. Note: orientation, width, and height
|
|
268
|
-
exif attributes are not copied since those are lost after image rotation.
|
|
269
|
-
|
|
270
|
-
* imageUri: original image URI as provided from JS
|
|
271
|
-
* dstPath: final image output path
|
|
272
|
-
* Returns true if copy was successful, false otherwise.
|
|
273
|
-
*/
|
|
274
|
-
public static boolean copyExif(Context context, Uri imageUri, String dstPath){
|
|
275
|
-
ExifInterface src = null;
|
|
276
|
-
ExifInterface dst = null;
|
|
277
|
-
|
|
278
|
-
try {
|
|
279
|
-
|
|
280
|
-
File file = getFileFromUri(context, imageUri);
|
|
281
|
-
if (!file.exists()) {
|
|
282
|
-
return false;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
src = new ExifInterface(file.getAbsolutePath());
|
|
286
|
-
dst = new ExifInterface(dstPath);
|
|
287
|
-
|
|
288
|
-
} catch (Exception ignored) {
|
|
289
|
-
Log.e("StreamChatReactNative::copyExif", "EXIF read failed", ignored);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if(src == null || dst == null){
|
|
293
|
-
return false;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
try{
|
|
297
|
-
|
|
298
|
-
for (String attr : EXIF_TO_COPY_ROTATED)
|
|
299
|
-
{
|
|
300
|
-
String value = src.getAttribute(attr);
|
|
301
|
-
if (value != null){
|
|
302
|
-
dst.setAttribute(attr, value);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
dst.saveAttributes();
|
|
306
|
-
|
|
307
|
-
} catch (Exception ignored) {
|
|
308
|
-
Log.e("StreamChatReactNative::copyExif", "EXIF copy failed", ignored);
|
|
309
|
-
return false;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
return true;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
163
|
/**
|
|
316
164
|
* Get orientation by reading Image metadata
|
|
317
165
|
*/
|
|
@@ -591,4 +439,3 @@ public class StreamChatReactNative {
|
|
|
591
439
|
return scaledImage;
|
|
592
440
|
}
|
|
593
441
|
}
|
|
594
|
-
|
|
@@ -4,8 +4,6 @@ import android.annotation.SuppressLint;
|
|
|
4
4
|
import android.graphics.Bitmap;
|
|
5
5
|
import android.net.Uri;
|
|
6
6
|
import android.os.AsyncTask;
|
|
7
|
-
import android.util.Log;
|
|
8
|
-
|
|
9
7
|
import androidx.annotation.Nullable;
|
|
10
8
|
import androidx.annotation.NonNull;
|
|
11
9
|
|
|
@@ -36,7 +34,7 @@ public class StreamChatReactNativeModule extends StreamChatReactNativeSpec {
|
|
|
36
34
|
}
|
|
37
35
|
|
|
38
36
|
@ReactMethod
|
|
39
|
-
public void createResizedImage(String uri, double width, double height, String format, double quality, String mode, boolean onlyScaleDown, Double rotation, @Nullable String outputPath,
|
|
37
|
+
public void createResizedImage(String uri, double width, double height, String format, double quality, String mode, boolean onlyScaleDown, Double rotation, @Nullable String outputPath, Promise promise) {
|
|
40
38
|
WritableMap options = Arguments.createMap();
|
|
41
39
|
options.putString("mode", mode);
|
|
42
40
|
options.putBoolean("onlyScaleDown", onlyScaleDown);
|
|
@@ -46,7 +44,7 @@ public class StreamChatReactNativeModule extends StreamChatReactNativeSpec {
|
|
|
46
44
|
@Override
|
|
47
45
|
protected void doInBackgroundGuarded(Void... params) {
|
|
48
46
|
try {
|
|
49
|
-
Object response = createResizedImageWithExceptions(uri, (int) width, (int) height, format, (int) quality, rotation.intValue(), outputPath,
|
|
47
|
+
Object response = createResizedImageWithExceptions(uri, (int) width, (int) height, format, (int) quality, rotation.intValue(), outputPath, options);
|
|
50
48
|
promise.resolve(response);
|
|
51
49
|
}
|
|
52
50
|
catch (IOException e) {
|
|
@@ -59,7 +57,6 @@ public class StreamChatReactNativeModule extends StreamChatReactNativeSpec {
|
|
|
59
57
|
@SuppressLint("LongLogTag")
|
|
60
58
|
private Object createResizedImageWithExceptions(String imagePath, int newWidth, int newHeight,
|
|
61
59
|
String compressFormatString, int quality, int rotation, String outputPath,
|
|
62
|
-
final boolean keepMeta,
|
|
63
60
|
final ReadableMap options) throws IOException {
|
|
64
61
|
|
|
65
62
|
Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.valueOf(compressFormatString);
|
|
@@ -89,16 +86,6 @@ public class StreamChatReactNativeModule extends StreamChatReactNativeSpec {
|
|
|
89
86
|
response.putDouble("size", resizedImage.length());
|
|
90
87
|
response.putDouble("width", scaledImage.getWidth());
|
|
91
88
|
response.putDouble("height", scaledImage.getHeight());
|
|
92
|
-
|
|
93
|
-
// Copy file's metadata/exif info if required
|
|
94
|
-
if(keepMeta){
|
|
95
|
-
try{
|
|
96
|
-
StreamChatReactNative.copyExif(this.getReactApplicationContext(), imageUri, resizedImage.getAbsolutePath());
|
|
97
|
-
}
|
|
98
|
-
catch(Exception ignored){
|
|
99
|
-
Log.e("StreamChatReactNative::createResizedImageWithExceptions", "EXIF copy failed", ignored);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
89
|
} else {
|
|
103
90
|
throw new IOException("Error getting resized image path");
|
|
104
91
|
}
|
|
@@ -12,5 +12,5 @@ abstract class StreamChatReactNativeSpec extends ReactContextBaseJavaModule {
|
|
|
12
12
|
super(context);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
public abstract void createResizedImage(String uri, double width, double height, String format, double quality, String mode, boolean onlyScaleDown, Double rotation, @Nullable String outputPath,
|
|
15
|
+
public abstract void createResizedImage(String uri, double width, double height, String format, double quality, String mode, boolean onlyScaleDown, Double rotation, @Nullable String outputPath, Promise promise);
|
|
16
16
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
#import "StreamChatReactNative.h"
|
|
2
2
|
#import <React/RCTLog.h>
|
|
3
|
-
#import <AssetsLibrary/AssetsLibrary.h>
|
|
4
|
-
#import <MobileCoreServices/MobileCoreServices.h>
|
|
5
3
|
|
|
6
4
|
#if __has_include(<React/RCTLog.h>)
|
|
7
5
|
#import <React/RCTLog.h>
|
|
@@ -19,12 +17,12 @@ NSString *moduleName = @"StreamChatReactNative";
|
|
|
19
17
|
|
|
20
18
|
RCT_EXPORT_MODULE()
|
|
21
19
|
|
|
22
|
-
RCT_REMAP_METHOD(createResizedImage, uri:(NSString *)uri width:(double)width height:(double)height format:(NSString *)format quality:(double)quality mode:(NSString *)mode onlyScaleDown:(BOOL)onlyScaleDown rotation:(nonnull NSNumber *)rotation outputPath:(NSString *)outputPath
|
|
20
|
+
RCT_REMAP_METHOD(createResizedImage, uri:(NSString *)uri width:(double)width height:(double)height format:(NSString *)format quality:(double)quality mode:(NSString *)mode onlyScaleDown:(BOOL)onlyScaleDown rotation:(nonnull NSNumber *)rotation outputPath:(NSString *)outputPath resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
|
|
23
21
|
{
|
|
24
|
-
[self createResizedImage:uri width:width height:height format:format quality:quality mode:mode onlyScaleDown:onlyScaleDown rotation:rotation outputPath:outputPath
|
|
22
|
+
[self createResizedImage:uri width:width height:height format:format quality:quality mode:mode onlyScaleDown:onlyScaleDown rotation:rotation outputPath:outputPath resolve:resolve reject:reject];
|
|
25
23
|
}
|
|
26
24
|
|
|
27
|
-
- (void)createResizedImage:(NSString *)uri width:(double)width height:(double)height format:(NSString *)format quality:(double)quality mode:(NSString *)mode onlyScaleDown:(BOOL)onlyScaleDown rotation:(nonnull NSNumber *)rotation outputPath:(NSString *)outputPath
|
|
25
|
+
- (void)createResizedImage:(NSString *)uri width:(double)width height:(double)height format:(NSString *)format quality:(double)quality mode:(NSString *)mode onlyScaleDown:(BOOL)onlyScaleDown rotation:(nonnull NSNumber *)rotation outputPath:(NSString *)outputPath resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
|
|
28
26
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
29
27
|
@try {
|
|
30
28
|
CGSize newSize = CGSizeMake(width, height);
|
|
@@ -57,7 +55,7 @@ RCT_REMAP_METHOD(createResizedImage, uri:(NSString *)uri width:(double)width hei
|
|
|
57
55
|
reject([NSString stringWithFormat: @"%ld", (long)error.code], error.description, nil);
|
|
58
56
|
return;
|
|
59
57
|
}
|
|
60
|
-
NSDictionary * response = transformImage(image,
|
|
58
|
+
NSDictionary * response = transformImage(image, [rotation integerValue], newSize, fullPath, format, (int)quality, @{@"mode": mode, @"onlyScaleDown": [NSNumber numberWithBool:onlyScaleDown]});
|
|
61
59
|
resolve(response);
|
|
62
60
|
}];
|
|
63
61
|
} @catch (NSException *exception) {
|
|
@@ -69,65 +67,21 @@ RCT_REMAP_METHOD(createResizedImage, uri:(NSString *)uri width:(double)width hei
|
|
|
69
67
|
|
|
70
68
|
|
|
71
69
|
|
|
72
|
-
bool saveImage(NSString * fullPath, UIImage * image, NSString * format, float quality
|
|
70
|
+
bool saveImage(NSString * fullPath, UIImage * image, NSString * format, float quality)
|
|
73
71
|
{
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
data = UIImagePNGRepresentation(image);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (data == nil) {
|
|
83
|
-
return NO;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
NSFileManager* fileManager = [NSFileManager defaultManager];
|
|
87
|
-
return [fileManager createFileAtPath:fullPath contents:data attributes:nil];
|
|
72
|
+
NSData* data = nil;
|
|
73
|
+
if ([format isEqualToString:@"JPEG"]) {
|
|
74
|
+
data = UIImageJPEGRepresentation(image, quality / 100.0);
|
|
75
|
+
} else if ([format isEqualToString:@"PNG"]) {
|
|
76
|
+
data = UIImagePNGRepresentation(image);
|
|
88
77
|
}
|
|
89
78
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
CFStringRef imgType = kUTTypeJPEG;
|
|
94
|
-
|
|
95
|
-
if ([format isEqualToString:@"JPEG"]) {
|
|
96
|
-
[metadata setObject:@(quality / 100.0) forKey:(__bridge NSString *)kCGImageDestinationLossyCompressionQuality];
|
|
97
|
-
}
|
|
98
|
-
else if([format isEqualToString:@"PNG"]){
|
|
99
|
-
imgType = kUTTypePNG;
|
|
100
|
-
}
|
|
101
|
-
else{
|
|
102
|
-
return NO;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
NSMutableData * destData = [NSMutableData data];
|
|
106
|
-
|
|
107
|
-
CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)destData, imgType, 1, NULL);
|
|
108
|
-
|
|
109
|
-
@try{
|
|
110
|
-
CGImageDestinationAddImage(destination, image.CGImage, (__bridge CFDictionaryRef) metadata);
|
|
111
|
-
|
|
112
|
-
// write final image data with metadata to our destination
|
|
113
|
-
if (CGImageDestinationFinalize(destination)){
|
|
114
|
-
|
|
115
|
-
NSFileManager* fileManager = [NSFileManager defaultManager];
|
|
116
|
-
return [fileManager createFileAtPath:fullPath contents:destData attributes:nil];
|
|
117
|
-
}
|
|
118
|
-
else{
|
|
119
|
-
return NO;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
@finally{
|
|
123
|
-
@try{
|
|
124
|
-
CFRelease(destination);
|
|
125
|
-
}
|
|
126
|
-
@catch(NSException *exception){
|
|
127
|
-
NSLog(@"Failed to release CGImageDestinationRef: %@", exception);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
79
|
+
if (data == nil) {
|
|
80
|
+
return NO;
|
|
130
81
|
}
|
|
82
|
+
|
|
83
|
+
NSFileManager* fileManager = [NSFileManager defaultManager];
|
|
84
|
+
return [fileManager createFileAtPath:fullPath contents:data attributes:nil];
|
|
131
85
|
}
|
|
132
86
|
|
|
133
87
|
NSString * generateFilePath(NSString * ext, NSString * outputPath)
|
|
@@ -268,81 +222,12 @@ UIImage* scaleImage (UIImage* image, CGSize toSize, NSString* mode, bool onlySca
|
|
|
268
222
|
return newImage;
|
|
269
223
|
}
|
|
270
224
|
|
|
271
|
-
// Returns the image's metadata, or nil if failed to retrieve it.
|
|
272
|
-
NSMutableDictionary * getImageMeta(NSString * path)
|
|
273
|
-
{
|
|
274
|
-
if([path hasPrefix:@"assets-library"]) {
|
|
275
|
-
|
|
276
|
-
__block NSMutableDictionary* res = nil;
|
|
277
|
-
|
|
278
|
-
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
|
|
279
|
-
{
|
|
280
|
-
|
|
281
|
-
NSDictionary *exif = [[myasset defaultRepresentation] metadata];
|
|
282
|
-
res = [exif mutableCopy];
|
|
283
|
-
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
|
|
287
|
-
NSURL *url = [NSURL URLWithString:[path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
|
|
288
|
-
|
|
289
|
-
[assetslibrary assetForURL:url resultBlock:resultblock failureBlock:^(NSError *error) { NSLog(@"error couldn't image from assets library"); }];
|
|
290
|
-
|
|
291
|
-
return res;
|
|
292
|
-
|
|
293
|
-
} else {
|
|
294
|
-
|
|
295
|
-
NSData* imageData = nil;
|
|
296
|
-
|
|
297
|
-
if ([path hasPrefix:@"data:"] || [path hasPrefix:@"file:"]) {
|
|
298
|
-
NSURL *imageUrl = [[NSURL alloc] initWithString:path];
|
|
299
|
-
imageData = [NSData dataWithContentsOfURL:imageUrl];
|
|
300
|
-
|
|
301
|
-
} else {
|
|
302
|
-
imageData = [NSData dataWithContentsOfFile:path];
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
if(imageData == nil){
|
|
306
|
-
NSLog(@"Could not get image file data to extract metadata.");
|
|
307
|
-
return nil;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)imageData, NULL);
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
if(source != nil){
|
|
314
|
-
|
|
315
|
-
CFDictionaryRef metaRef = CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
|
|
316
|
-
|
|
317
|
-
// release CF image
|
|
318
|
-
CFRelease(source);
|
|
319
|
-
|
|
320
|
-
CFMutableDictionaryRef metaRefMutable = CFDictionaryCreateMutableCopy(NULL, 0, metaRef);
|
|
321
|
-
|
|
322
|
-
// release the source meta ref now that we've copie it
|
|
323
|
-
CFRelease(metaRef);
|
|
324
|
-
|
|
325
|
-
// bridge CF object so it auto releases
|
|
326
|
-
NSMutableDictionary* res = (NSMutableDictionary *)CFBridgingRelease(metaRefMutable);
|
|
327
|
-
|
|
328
|
-
return res;
|
|
329
|
-
|
|
330
|
-
}
|
|
331
|
-
else{
|
|
332
|
-
return nil;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
225
|
NSDictionary * transformImage(UIImage *image,
|
|
339
|
-
NSString * originalPath,
|
|
340
226
|
int rotation,
|
|
341
227
|
CGSize newSize,
|
|
342
228
|
NSString* fullPath,
|
|
343
229
|
NSString* format,
|
|
344
230
|
int quality,
|
|
345
|
-
BOOL keepMeta,
|
|
346
231
|
NSDictionary* options)
|
|
347
232
|
{
|
|
348
233
|
if (image == nil) {
|
|
@@ -368,25 +253,8 @@ NSDictionary * transformImage(UIImage *image,
|
|
|
368
253
|
if (scaledImage == nil) {
|
|
369
254
|
[NSException raise:moduleName format:@"Can't resize the image."];
|
|
370
255
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
NSMutableDictionary *metadata = nil;
|
|
374
|
-
|
|
375
|
-
// to be consistent with Android, we will only allow JPEG
|
|
376
|
-
// to do this.
|
|
377
|
-
if(keepMeta && [format isEqualToString:@"JPEG"]){
|
|
378
|
-
|
|
379
|
-
metadata = getImageMeta(originalPath);
|
|
380
|
-
|
|
381
|
-
// remove orientation (since we fix it)
|
|
382
|
-
// width/height meta is adjusted automatically
|
|
383
|
-
// NOTE: This might still leave some stale values due to resize
|
|
384
|
-
metadata[(NSString*)kCGImagePropertyOrientation] = @(1);
|
|
385
|
-
|
|
386
|
-
}
|
|
387
|
-
|
|
388
256
|
// Compress and save the image
|
|
389
|
-
if (!saveImage(fullPath, scaledImage, format, quality
|
|
257
|
+
if (!saveImage(fullPath, scaledImage, format, quality)) {
|
|
390
258
|
[NSException raise:moduleName format:@"Can't save the image. Check your compression format and your output path"];
|
|
391
259
|
}
|
|
392
260
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stream-chat-react-native",
|
|
3
3
|
"description": "The official React Native SDK for Stream Chat, a service for building chat applications",
|
|
4
|
-
"version": "9.0.0-beta.
|
|
4
|
+
"version": "9.0.0-beta.10",
|
|
5
5
|
"homepage": "https://www.npmjs.com/package/stream-chat-react-native",
|
|
6
6
|
"author": {
|
|
7
7
|
"company": "Stream.io Inc",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"es6-symbol": "^3.1.3",
|
|
31
31
|
"mime": "^4.0.7",
|
|
32
|
-
"stream-chat-react-native-core": "9.0.0-beta.
|
|
32
|
+
"stream-chat-react-native-core": "9.0.0-beta.10"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"@react-native-camera-roll/camera-roll": ">=7.8.0",
|
package/src/native/index.tsx
CHANGED
|
@@ -24,7 +24,6 @@ async function createResizedImage(
|
|
|
24
24
|
quality: number,
|
|
25
25
|
rotation: number = 0,
|
|
26
26
|
outputPath?: string | null,
|
|
27
|
-
keepMeta = false,
|
|
28
27
|
options: Options = defaultOptions,
|
|
29
28
|
): Promise<Response> {
|
|
30
29
|
const { mode, onlyScaleDown } = { ...defaultOptions, ...options };
|
|
@@ -39,7 +38,6 @@ async function createResizedImage(
|
|
|
39
38
|
onlyScaleDown,
|
|
40
39
|
rotation,
|
|
41
40
|
outputPath,
|
|
42
|
-
keepMeta,
|
|
43
41
|
);
|
|
44
42
|
}
|
|
45
43
|
|