Skip to content

Commit cb79b4a

Browse files
committed
[FEATURE] added size(bytes) and mime type for returned images
1 parent d93e918 commit cb79b4a

File tree

7 files changed

+92
-53
lines changed

7 files changed

+92
-53
lines changed

android/react-native-image-crop-picker.iml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@
105105
<orderEntry type="library" exported="" name="okhttp-ws-2.5.0" level="project" />
106106
<orderEntry type="library" exported="" name="okio-1.6.0" level="project" />
107107
<orderEntry type="library" exported="" name="okhttp-2.5.0" level="project" />
108-
<orderEntry type="library" exported="" name="jsr305-3.0.0" level="project" />
109108
<orderEntry type="library" exported="" name="stetho-1.2.0" level="project" />
109+
<orderEntry type="library" exported="" name="jsr305-3.0.0" level="project" />
110110
<orderEntry type="library" exported="" name="fbcore-0.8.1" level="project" />
111111
<orderEntry type="library" exported="" name="commons-cli-1.2" level="project" />
112112
<orderEntry type="library" exported="" name="recyclerview-v7-23.0.1" level="project" />

android/src/main/java/com/reactnative/picker/PickerModule.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
import android.database.Cursor;
77
import android.graphics.Bitmap;
88
import android.graphics.BitmapFactory;
9+
import android.graphics.PixelFormat;
910
import android.net.Uri;
11+
import android.os.Build;
1012
import android.provider.DocumentsContract;
1113
import android.provider.MediaStore;
1214

@@ -88,6 +90,16 @@ public void openPicker(final ReadableMap options, final Promise promise) {
8890
}
8991
}
9092

93+
public static int byteSizeOf(Bitmap bitmap) {
94+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
95+
return bitmap.getAllocationByteCount();
96+
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
97+
return bitmap.getByteCount();
98+
} else {
99+
return bitmap.getRowBytes() * bitmap.getHeight();
100+
}
101+
}
102+
91103
private WritableMap getImage(Uri uri, boolean resolvePath) {
92104
WritableMap image = new WritableNativeMap();
93105
String path = uri.getPath();
@@ -97,12 +109,20 @@ private WritableMap getImage(Uri uri, boolean resolvePath) {
97109
}
98110

99111
BitmapFactory.Options options = new BitmapFactory.Options();
100-
options.inJustDecodeBounds = true;
101-
BitmapFactory.decodeFile(path, options);
102112

113+
114+
Bitmap bitmap = BitmapFactory.decodeFile(path, options);
103115
image.putString("path", "file://" + path);
104116
image.putInt("width", options.outWidth);
105117
image.putInt("height", options.outHeight);
118+
image.putString("mime", options.outMimeType);
119+
120+
if (bitmap != null) {
121+
image.putInt("size", byteSizeOf(bitmap));
122+
bitmap.recycle();
123+
} else {
124+
image.putInt("size", 0);
125+
}
106126

107127
return image;
108128
}

example/android/app/app.iml

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,6 @@
6464
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
6565
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
6666
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
67-
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
68-
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
69-
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
70-
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
71-
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
72-
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
73-
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
74-
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
7567
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
7668
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
7769
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
@@ -80,8 +72,17 @@
8072
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
8173
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
8274
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
75+
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
76+
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
77+
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
78+
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
79+
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
80+
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
81+
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
82+
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
8383
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
8484
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
85+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
8586
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
8687
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
8788
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
@@ -98,12 +99,17 @@
9899
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.react/react-native/0.26.1/jars" />
99100
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/org.webkit/android-jsc/r174650/jars" />
100101
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
102+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-classes" />
103+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-runtime-classes" />
101104
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-safeguard" />
105+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-verifier" />
102106
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
103107
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
104108
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
105109
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
110+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
106111
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
112+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" />
107113
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
108114
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
109115
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />

example/app.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export default class App extends Component {
3636
height: 300,
3737
cropping: cropit
3838
}).then(image => {
39+
console.log('received image', image);
3940
this.setState({
4041
image: {uri: image.path, width: image.width, height: image.height},
4142
images: null
@@ -50,6 +51,7 @@ export default class App extends Component {
5051
this.setState({
5152
image: null,
5253
images: images.map(i => {
54+
console.log('received image', i);
5355
return {uri: i.path, width: i.width, height: i.height};
5456
})
5557
});

example/ios/Podfile.lock

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
PODS:
22
- QBImagePickerController (3.4.0)
3-
- React (0.26.1):
4-
- React/Core (= 0.26.1)
5-
- react-native-image-crop-picker (0.2.6):
3+
- React (0.27.2):
4+
- React/Core (= 0.27.2)
5+
- react-native-image-crop-picker (0.3.1):
66
- QBImagePickerController (= 3.4.0)
77
- React (>= 0.26.1)
88
- RSKImageCropper (= 1.5.1)
99
- UIImage-Resize (~> 1.0)
10-
- React/Core (0.26.1)
11-
- React/RCTImage (0.26.1):
10+
- React/Core (0.27.2)
11+
- React/RCTImage (0.27.2):
1212
- React/Core
1313
- React/RCTNetwork
14-
- React/RCTNetwork (0.26.1):
14+
- React/RCTNetwork (0.27.2):
1515
- React/Core
16-
- React/RCTText (0.26.1):
16+
- React/RCTText (0.27.2):
1717
- React/Core
18-
- React/RCTWebSocket (0.26.1):
18+
- React/RCTWebSocket (0.27.2):
1919
- React/Core
2020
- RSKImageCropper (1.5.1)
2121
- UIImage-Resize (1.0.1)
@@ -36,8 +36,8 @@ EXTERNAL SOURCES:
3636

3737
SPEC CHECKSUMS:
3838
QBImagePickerController: d54cf93db6decf26baf6ed3472f336ef35cae022
39-
React: 9a7eb5f6e7146734fb50ab17f515087d302d5cca
40-
react-native-image-crop-picker: 74b2f62969408d309d510bb5b5ea1c86b894a678
39+
React: ed545be51aeb5c3988abb0b17bf174b87aac1a17
40+
react-native-image-crop-picker: 25000b16a716be2b298998c2d959cf8d7565d24a
4141
RSKImageCropper: edd65fedb3734332818deb139906d6b7f54b8a44
4242
UIImage-Resize: fa776860f10e6900bbaf53a73e494bdceaaccc77
4343

example/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"start": "node node_modules/react-native/local-cli/cli.js start"
77
},
88
"dependencies": {
9-
"react": "15.0.2",
10-
"react-native": "^0.26.1"
9+
"react": "^15.1.0",
10+
"react-native": "^0.27.2"
1111
}
1212
}

ios/ImageCropPicker.m

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,21 @@ - (instancetype)init
2929
@"height": @200
3030
};
3131
}
32-
32+
3333
return self;
3434
}
3535

3636
RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
3737
resolver:(RCTPromiseResolveBlock)resolve
3838
rejecter:(RCTPromiseRejectBlock)reject) {
39-
39+
4040
self.resolve = resolve;
4141
self.reject = reject;
4242
self.options = [NSMutableDictionary dictionaryWithDictionary:self.defaultOptions];
4343
for (NSString *key in options.keyEnumerator) {
4444
[self.options setValue:options[key] forKey:key];
4545
}
46-
46+
4747
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
4848
dispatch_async(dispatch_get_main_queue(), ^{
4949
// init picker
@@ -54,7 +54,7 @@ - (instancetype)init
5454
imagePickerController.maximumNumberOfSelection = [[self.options objectForKey:@"maxFiles"] intValue];
5555
imagePickerController.showsNumberOfSelectedAssets = YES;
5656
imagePickerController.mediaType = QBImagePickerMediaTypeImage;
57-
57+
5858
UIViewController *root = [[[[UIApplication sharedApplication] delegate]
5959
window] rootViewController];
6060
[root presentViewController:imagePickerController
@@ -67,67 +67,76 @@ - (instancetype)init
6767
- (void)qb_imagePickerController:
6868
(QBImagePickerController *)imagePickerController
6969
didFinishPickingAssets:(NSArray *)assets {
70-
70+
7171
PHImageManager *manager = [PHImageManager defaultManager];
72-
72+
7373
if ([[[self options] objectForKey:@"multiple"] boolValue]) {
7474
NSMutableArray *images = [[NSMutableArray alloc] init];
7575
PHImageRequestOptions* options = [[PHImageRequestOptions alloc] init];
7676
options.synchronous = YES;
77-
77+
7878
for (PHAsset *asset in assets) {
7979
[manager
8080
requestImageDataForAsset:asset
8181
options:options
8282
resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
83-
NSString *filePath = [self persistFile:imageData];
83+
UIImage *image = [UIImage imageWithData:imageData];
84+
NSData *data = UIImageJPEGRepresentation(image, 1);
85+
86+
NSString *filePath = [self persistFile:data];
8487
if (filePath == nil) {
8588
self.reject(ERROR_CANNOT_SAVE_IMAGE_KEY, ERROR_CANNOT_SAVE_IMAGE_MSG, nil);
8689
return;
8790
}
88-
91+
8992
[images addObject:@{
9093
@"path": filePath,
9194
@"width": @(asset.pixelWidth),
92-
@"height": @(asset.pixelHeight)
95+
@"height": @(asset.pixelHeight),
96+
@"mime": @"image/jpeg",
97+
@"size": [NSNumber numberWithUnsignedInteger:data.length]
9398
}];
9499
}];
95100
}
96-
101+
97102
self.resolve(images);
98103
[imagePickerController dismissViewControllerAnimated:YES completion:nil];
99104
} else {
100105
PHAsset *asset = [assets objectAtIndex:0];
101-
106+
102107
[manager
103108
requestImageDataForAsset:asset
104109
options:nil
105110
resultHandler:^(NSData *imageData, NSString *dataUTI,
106111
UIImageOrientation orientation,
107112
NSDictionary *info) {
108-
113+
109114
if ([[[self options] objectForKey:@"cropping"] boolValue]) {
110115
UIImage *image = [UIImage imageWithData:imageData];
111116
RSKImageCropViewController *imageCropVC = [[RSKImageCropViewController alloc] initWithImage:image cropMode:RSKImageCropModeCustom];
112-
117+
113118
imageCropVC.avoidEmptySpaceAroundImage = YES;
114119
imageCropVC.dataSource = self;
115120
imageCropVC.delegate = self;
116-
121+
117122
UIViewController *root = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
118123
[imagePickerController dismissViewControllerAnimated:YES completion:nil];
119124
[root presentViewController:imageCropVC animated:YES completion:nil];
120125
} else {
121-
NSString *filePath = [self persistFile:imageData];
126+
UIImage *image = [UIImage imageWithData:imageData];
127+
NSData *data = UIImageJPEGRepresentation(image, 1);
128+
NSString *filePath = [self persistFile:data];
122129
if (filePath == nil) {
123130
self.reject(ERROR_CANNOT_SAVE_IMAGE_KEY, ERROR_CANNOT_SAVE_IMAGE_MSG, nil);
124131
return;
125132
}
126-
133+
127134
self.resolve(@{
128135
@"path": filePath,
129136
@"width": @(asset.pixelWidth),
130-
@"height": @(asset.pixelHeight)
137+
@"height": @(asset.pixelHeight),
138+
@"mime": @"image/jpeg",
139+
@"size": [NSNumber numberWithUnsignedInteger:data.length]
131140
});
132141
[imagePickerController dismissViewControllerAnimated:YES completion:nil];
133142
}
@@ -148,14 +157,14 @@ - (CGRect)imageCropViewControllerCustomMaskRect:
148157
CGSize maskSize = CGSizeMake(
149158
[[self.options objectForKey:@"width"] intValue],
150159
[[self.options objectForKey:@"height"] intValue]);
151-
160+
152161
CGFloat viewWidth = CGRectGetWidth(controller.view.frame);
153162
CGFloat viewHeight = CGRectGetHeight(controller.view.frame);
154-
163+
155164
CGRect maskRect = CGRectMake((viewWidth - maskSize.width) * 0.5f,
156165
(viewHeight - maskSize.height) * 0.5f,
157166
maskSize.width, maskSize.height);
158-
167+
159168
return maskRect;
160169
}
161170

@@ -165,7 +174,7 @@ - (CGRect) scaleRect:(RSKImageCropViewController *)controller {
165174
CGRect rect = controller.maskRect;
166175
CGFloat viewWidth = CGRectGetWidth(controller.view.frame);
167176
CGFloat viewHeight = CGRectGetHeight(controller.view.frame);
168-
177+
169178
if (rect.size.width > viewWidth) {
170179
float scaleFactor = viewWidth / rect.size.width;
171180
rect.size.width *= scaleFactor;
@@ -179,7 +188,7 @@ - (CGRect) scaleRect:(RSKImageCropViewController *)controller {
179188
rect.origin.x = viewWidth / 2 * 0.5f;
180189
rect.origin.y = 0;
181190
}
182-
191+
183192
return rect;
184193
}
185194

@@ -212,25 +221,27 @@ - (void)imageCropViewControllerDidCancelCrop:
212221
- (void)imageCropViewController:(RSKImageCropViewController *)controller
213222
didCropImage:(UIImage *)croppedImage
214223
usingCropRect:(CGRect)cropRect {
215-
224+
216225
// we have correct rect, but not correct dimensions
217226
// so resize image
218227
CGSize resizedImageSize = CGSizeMake([[[self options] objectForKey:@"width"] intValue], [[[self options] objectForKey:@"height"] intValue]);
219228
UIImage *resizedImage = [croppedImage resizedImageToFitInSize:resizedImageSize scaleIfSmaller:YES];
220229
NSData *data = UIImageJPEGRepresentation(resizedImage, 1);
221-
230+
222231
NSString *filePath = [self persistFile:data];
223232
if (filePath == nil) {
224233
self.reject(ERROR_CANNOT_SAVE_IMAGE_KEY, ERROR_CANNOT_SAVE_IMAGE_MSG, nil);
225234
return;
226235
}
227-
236+
228237
NSDictionary *image = @{
229238
@"path": filePath,
230239
@"width": @(resizedImage.size.width),
231-
@"height": @(resizedImage.size.height)
240+
@"height": @(resizedImage.size.height),
241+
@"mime": @"image/jpeg",
242+
@"size": [NSNumber numberWithUnsignedInteger:data.length]
232243
};
233-
244+
234245
self.resolve(image);
235246
[controller dismissViewControllerAnimated:YES completion:nil];
236247
}
@@ -241,13 +252,13 @@ - (NSString*) persistFile:(NSData*)data {
241252
// create temp file
242253
NSString *filePath = [NSTemporaryDirectory() stringByAppendingString:[[NSUUID UUID] UUIDString]];
243254
filePath = [filePath stringByAppendingString:@".jpg"];
244-
255+
245256
// save cropped file
246257
BOOL status = [data writeToFile:filePath atomically:YES];
247258
if (!status) {
248259
return nil;
249260
}
250-
261+
251262
return filePath;
252263
}
253264

0 commit comments

Comments
 (0)