mirror of
https://github.com/status-im/react-native-image-crop-picker.git
synced 2025-02-23 02:48:12 +00:00
[FEATURE] added size(bytes) and mime type for returned images
This commit is contained in:
parent
d93e918450
commit
cb79b4adc6
@ -105,8 +105,8 @@
|
||||
<orderEntry type="library" exported="" name="okhttp-ws-2.5.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="okio-1.6.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="okhttp-2.5.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="jsr305-3.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="stetho-1.2.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="jsr305-3.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="fbcore-0.8.1" level="project" />
|
||||
<orderEntry type="library" exported="" name="commons-cli-1.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="recyclerview-v7-23.0.1" level="project" />
|
||||
|
@ -6,7 +6,9 @@ import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.MediaStore;
|
||||
|
||||
@ -88,6 +90,16 @@ public class PickerModule extends ReactContextBaseJavaModule implements Activity
|
||||
}
|
||||
}
|
||||
|
||||
public static int byteSizeOf(Bitmap bitmap) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
return bitmap.getAllocationByteCount();
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
|
||||
return bitmap.getByteCount();
|
||||
} else {
|
||||
return bitmap.getRowBytes() * bitmap.getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
private WritableMap getImage(Uri uri, boolean resolvePath) {
|
||||
WritableMap image = new WritableNativeMap();
|
||||
String path = uri.getPath();
|
||||
@ -97,12 +109,20 @@ public class PickerModule extends ReactContextBaseJavaModule implements Activity
|
||||
}
|
||||
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(path, options);
|
||||
|
||||
|
||||
Bitmap bitmap = BitmapFactory.decodeFile(path, options);
|
||||
image.putString("path", "file://" + path);
|
||||
image.putInt("width", options.outWidth);
|
||||
image.putInt("height", options.outHeight);
|
||||
image.putString("mime", options.outMimeType);
|
||||
|
||||
if (bitmap != null) {
|
||||
image.putInt("size", byteSizeOf(bitmap));
|
||||
bitmap.recycle();
|
||||
} else {
|
||||
image.putInt("size", 0);
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
@ -64,14 +64,6 @@
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||
@ -80,8 +72,17 @@
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
|
||||
@ -98,12 +99,17 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.react/react-native/0.26.1/jars" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/org.webkit/android-jsc/r174650/jars" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-runtime-classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-safeguard" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-verifier" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
|
@ -36,6 +36,7 @@ export default class App extends Component {
|
||||
height: 300,
|
||||
cropping: cropit
|
||||
}).then(image => {
|
||||
console.log('received image', image);
|
||||
this.setState({
|
||||
image: {uri: image.path, width: image.width, height: image.height},
|
||||
images: null
|
||||
@ -50,6 +51,7 @@ export default class App extends Component {
|
||||
this.setState({
|
||||
image: null,
|
||||
images: images.map(i => {
|
||||
console.log('received image', i);
|
||||
return {uri: i.path, width: i.width, height: i.height};
|
||||
})
|
||||
});
|
||||
|
@ -1,21 +1,21 @@
|
||||
PODS:
|
||||
- QBImagePickerController (3.4.0)
|
||||
- React (0.26.1):
|
||||
- React/Core (= 0.26.1)
|
||||
- react-native-image-crop-picker (0.2.6):
|
||||
- React (0.27.2):
|
||||
- React/Core (= 0.27.2)
|
||||
- react-native-image-crop-picker (0.3.1):
|
||||
- QBImagePickerController (= 3.4.0)
|
||||
- React (>= 0.26.1)
|
||||
- RSKImageCropper (= 1.5.1)
|
||||
- UIImage-Resize (~> 1.0)
|
||||
- React/Core (0.26.1)
|
||||
- React/RCTImage (0.26.1):
|
||||
- React/Core (0.27.2)
|
||||
- React/RCTImage (0.27.2):
|
||||
- React/Core
|
||||
- React/RCTNetwork
|
||||
- React/RCTNetwork (0.26.1):
|
||||
- React/RCTNetwork (0.27.2):
|
||||
- React/Core
|
||||
- React/RCTText (0.26.1):
|
||||
- React/RCTText (0.27.2):
|
||||
- React/Core
|
||||
- React/RCTWebSocket (0.26.1):
|
||||
- React/RCTWebSocket (0.27.2):
|
||||
- React/Core
|
||||
- RSKImageCropper (1.5.1)
|
||||
- UIImage-Resize (1.0.1)
|
||||
@ -36,8 +36,8 @@ EXTERNAL SOURCES:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
QBImagePickerController: d54cf93db6decf26baf6ed3472f336ef35cae022
|
||||
React: 9a7eb5f6e7146734fb50ab17f515087d302d5cca
|
||||
react-native-image-crop-picker: 74b2f62969408d309d510bb5b5ea1c86b894a678
|
||||
React: ed545be51aeb5c3988abb0b17bf174b87aac1a17
|
||||
react-native-image-crop-picker: 25000b16a716be2b298998c2d959cf8d7565d24a
|
||||
RSKImageCropper: edd65fedb3734332818deb139906d6b7f54b8a44
|
||||
UIImage-Resize: fa776860f10e6900bbaf53a73e494bdceaaccc77
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
"start": "node node_modules/react-native/local-cli/cli.js start"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "15.0.2",
|
||||
"react-native": "^0.26.1"
|
||||
"react": "^15.1.0",
|
||||
"react-native": "^0.27.2"
|
||||
}
|
||||
}
|
||||
|
@ -29,21 +29,21 @@ RCT_EXPORT_MODULE();
|
||||
@"height": @200
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
|
||||
|
||||
self.resolve = resolve;
|
||||
self.reject = reject;
|
||||
self.options = [NSMutableDictionary dictionaryWithDictionary:self.defaultOptions];
|
||||
for (NSString *key in options.keyEnumerator) {
|
||||
[self.options setValue:options[key] forKey:key];
|
||||
}
|
||||
|
||||
|
||||
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
// init picker
|
||||
@ -54,7 +54,7 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
|
||||
imagePickerController.maximumNumberOfSelection = [[self.options objectForKey:@"maxFiles"] intValue];
|
||||
imagePickerController.showsNumberOfSelectedAssets = YES;
|
||||
imagePickerController.mediaType = QBImagePickerMediaTypeImage;
|
||||
|
||||
|
||||
UIViewController *root = [[[[UIApplication sharedApplication] delegate]
|
||||
window] rootViewController];
|
||||
[root presentViewController:imagePickerController
|
||||
@ -67,67 +67,76 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
|
||||
- (void)qb_imagePickerController:
|
||||
(QBImagePickerController *)imagePickerController
|
||||
didFinishPickingAssets:(NSArray *)assets {
|
||||
|
||||
|
||||
PHImageManager *manager = [PHImageManager defaultManager];
|
||||
|
||||
|
||||
if ([[[self options] objectForKey:@"multiple"] boolValue]) {
|
||||
NSMutableArray *images = [[NSMutableArray alloc] init];
|
||||
PHImageRequestOptions* options = [[PHImageRequestOptions alloc] init];
|
||||
options.synchronous = YES;
|
||||
|
||||
|
||||
for (PHAsset *asset in assets) {
|
||||
[manager
|
||||
requestImageDataForAsset:asset
|
||||
options:options
|
||||
resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
|
||||
NSString *filePath = [self persistFile:imageData];
|
||||
UIImage *image = [UIImage imageWithData:imageData];
|
||||
NSData *data = UIImageJPEGRepresentation(image, 1);
|
||||
|
||||
NSString *filePath = [self persistFile:data];
|
||||
if (filePath == nil) {
|
||||
self.reject(ERROR_CANNOT_SAVE_IMAGE_KEY, ERROR_CANNOT_SAVE_IMAGE_MSG, nil);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[images addObject:@{
|
||||
@"path": filePath,
|
||||
@"width": @(asset.pixelWidth),
|
||||
@"height": @(asset.pixelHeight)
|
||||
@"height": @(asset.pixelHeight),
|
||||
@"mime": @"image/jpeg",
|
||||
@"size": [NSNumber numberWithUnsignedInteger:data.length]
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
self.resolve(images);
|
||||
[imagePickerController dismissViewControllerAnimated:YES completion:nil];
|
||||
} else {
|
||||
PHAsset *asset = [assets objectAtIndex:0];
|
||||
|
||||
|
||||
[manager
|
||||
requestImageDataForAsset:asset
|
||||
options:nil
|
||||
resultHandler:^(NSData *imageData, NSString *dataUTI,
|
||||
UIImageOrientation orientation,
|
||||
NSDictionary *info) {
|
||||
|
||||
|
||||
if ([[[self options] objectForKey:@"cropping"] boolValue]) {
|
||||
UIImage *image = [UIImage imageWithData:imageData];
|
||||
RSKImageCropViewController *imageCropVC = [[RSKImageCropViewController alloc] initWithImage:image cropMode:RSKImageCropModeCustom];
|
||||
|
||||
|
||||
imageCropVC.avoidEmptySpaceAroundImage = YES;
|
||||
imageCropVC.dataSource = self;
|
||||
imageCropVC.delegate = self;
|
||||
|
||||
|
||||
UIViewController *root = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
|
||||
[imagePickerController dismissViewControllerAnimated:YES completion:nil];
|
||||
[root presentViewController:imageCropVC animated:YES completion:nil];
|
||||
} else {
|
||||
NSString *filePath = [self persistFile:imageData];
|
||||
UIImage *image = [UIImage imageWithData:imageData];
|
||||
NSData *data = UIImageJPEGRepresentation(image, 1);
|
||||
NSString *filePath = [self persistFile:data];
|
||||
if (filePath == nil) {
|
||||
self.reject(ERROR_CANNOT_SAVE_IMAGE_KEY, ERROR_CANNOT_SAVE_IMAGE_MSG, nil);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
self.resolve(@{
|
||||
@"path": filePath,
|
||||
@"width": @(asset.pixelWidth),
|
||||
@"height": @(asset.pixelHeight)
|
||||
@"height": @(asset.pixelHeight),
|
||||
@"mime": @"image/jpeg",
|
||||
@"size": [NSNumber numberWithUnsignedInteger:data.length]
|
||||
});
|
||||
[imagePickerController dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
@ -148,14 +157,14 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
|
||||
CGSize maskSize = CGSizeMake(
|
||||
[[self.options objectForKey:@"width"] intValue],
|
||||
[[self.options objectForKey:@"height"] intValue]);
|
||||
|
||||
|
||||
CGFloat viewWidth = CGRectGetWidth(controller.view.frame);
|
||||
CGFloat viewHeight = CGRectGetHeight(controller.view.frame);
|
||||
|
||||
|
||||
CGRect maskRect = CGRectMake((viewWidth - maskSize.width) * 0.5f,
|
||||
(viewHeight - maskSize.height) * 0.5f,
|
||||
maskSize.width, maskSize.height);
|
||||
|
||||
|
||||
return maskRect;
|
||||
}
|
||||
|
||||
@ -165,7 +174,7 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
|
||||
CGRect rect = controller.maskRect;
|
||||
CGFloat viewWidth = CGRectGetWidth(controller.view.frame);
|
||||
CGFloat viewHeight = CGRectGetHeight(controller.view.frame);
|
||||
|
||||
|
||||
if (rect.size.width > viewWidth) {
|
||||
float scaleFactor = viewWidth / rect.size.width;
|
||||
rect.size.width *= scaleFactor;
|
||||
@ -179,7 +188,7 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
|
||||
rect.origin.x = viewWidth / 2 * 0.5f;
|
||||
rect.origin.y = 0;
|
||||
}
|
||||
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
@ -212,25 +221,27 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
|
||||
- (void)imageCropViewController:(RSKImageCropViewController *)controller
|
||||
didCropImage:(UIImage *)croppedImage
|
||||
usingCropRect:(CGRect)cropRect {
|
||||
|
||||
|
||||
// we have correct rect, but not correct dimensions
|
||||
// so resize image
|
||||
CGSize resizedImageSize = CGSizeMake([[[self options] objectForKey:@"width"] intValue], [[[self options] objectForKey:@"height"] intValue]);
|
||||
UIImage *resizedImage = [croppedImage resizedImageToFitInSize:resizedImageSize scaleIfSmaller:YES];
|
||||
NSData *data = UIImageJPEGRepresentation(resizedImage, 1);
|
||||
|
||||
|
||||
NSString *filePath = [self persistFile:data];
|
||||
if (filePath == nil) {
|
||||
self.reject(ERROR_CANNOT_SAVE_IMAGE_KEY, ERROR_CANNOT_SAVE_IMAGE_MSG, nil);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
NSDictionary *image = @{
|
||||
@"path": filePath,
|
||||
@"width": @(resizedImage.size.width),
|
||||
@"height": @(resizedImage.size.height)
|
||||
@"height": @(resizedImage.size.height),
|
||||
@"mime": @"image/jpeg",
|
||||
@"size": [NSNumber numberWithUnsignedInteger:data.length]
|
||||
};
|
||||
|
||||
|
||||
self.resolve(image);
|
||||
[controller dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
@ -241,13 +252,13 @@ RCT_EXPORT_METHOD(openPicker:(NSDictionary *)options
|
||||
// create temp file
|
||||
NSString *filePath = [NSTemporaryDirectory() stringByAppendingString:[[NSUUID UUID] UUIDString]];
|
||||
filePath = [filePath stringByAppendingString:@".jpg"];
|
||||
|
||||
|
||||
// save cropped file
|
||||
BOOL status = [data writeToFile:filePath atomically:YES];
|
||||
if (!status) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
return filePath;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user