Commit 3abe68e8 authored by cookiej's avatar cookiej

[Add] 支持记录当前选中的图片数组

parent ab9db089
...@@ -19,7 +19,9 @@ ...@@ -19,7 +19,9 @@
* 支持单选、多选,类型包括图片、GIF * 支持单选、多选,类型包括图片、GIF
* 可自定义裁剪区域大小,支持圆形裁剪 * 可自定义裁剪区域大小,支持圆形裁剪
* 可设置压缩质量 * 可设置压缩质量
* 支持返回图片 base64 编码 * 可设置是否返回图片 base64 编码
* 支持记录当前已选中的图片
* 支持删除指定下标的图片
## 运行截图 ## 运行截图
...@@ -214,6 +216,19 @@ handleSelectPhoto = async () => { ...@@ -214,6 +216,19 @@ handleSelectPhoto = async () => {
} }
} }
``` ```
### 移除选中图片
在 React Native 页面移除选中的图片后,需调用 `removePhotoAtIndex` 方法,来删除原生中保存的图片数组,确保下次进入图片选择时,已选中的图片保持一致:
```javascript
handleDeletePhoto = index => {
const { selectedPhotos: oldPhotos } = this.state;
const selectedPhotos = oldPhotos.filter((photo, photoIndex) => photoIndex !== index);
// 更新原生图片数组
SYImagePicker.removePhotoAtIndex(index);
// 更新 RN 页面
this.setState({ selectedPhotos });
}
```
### 调用相机 ### 调用相机
相机功能调用 `openCamera` 方法,一样支持 Callback 和 Promise 两种形式,结果参数也保持一致。 相机功能调用 `openCamera` 方法,一样支持 Callback 和 Promise 两种形式,结果参数也保持一致。
......
...@@ -88,6 +88,17 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -88,6 +88,17 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
PictureFileUtils.deleteCacheDirFile(currentActivity); PictureFileUtils.deleteCacheDirFile(currentActivity);
} }
/**
* 移除选中的图片
* @param {int} index 要移除的图片下标
*/
@ReactMethod
public void removePhotoAtIndex(int index) {
if (selectList != null && selectList.size() > index) {
selectList.remove(index);
}
}
/** /**
* 打开相册选择 * 打开相册选择
*/ */
...@@ -139,6 +150,7 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -139,6 +150,7 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
.synOrAsy(true)//同步true或异步false 压缩 默认同步 .synOrAsy(true)//同步true或异步false 压缩 默认同步
.rotateEnabled(true) // 裁剪是否可旋转图片 true or false .rotateEnabled(true) // 裁剪是否可旋转图片 true or false
.scaleEnabled(true)// 裁剪是否可放大缩小图片 true or false .scaleEnabled(true)// 裁剪是否可放大缩小图片 true or false
.selectionMedia(selectList) // 当前已选中的图片 List
//.videoQuality(0)// 视频录制质量 0 or 1 int //.videoQuality(0)// 视频录制质量 0 or 1 int
//.videoMaxSecond(15)// 显示多少秒以内的视频or音频也可适用 int //.videoMaxSecond(15)// 显示多少秒以内的视频or音频也可适用 int
//.videoMinSecond(10)// 显示多少秒以内的视频or音频也可适用 int //.videoMinSecond(10)// 显示多少秒以内的视频or音频也可适用 int
...@@ -185,11 +197,15 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -185,11 +197,15 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
switch (requestCode) { switch (requestCode) {
case PictureConfig.CHOOSE_REQUEST: case PictureConfig.CHOOSE_REQUEST:
selectList = PictureSelector.obtainMultipleResult(data); List<LocalMedia> tmpSelectList = PictureSelector.obtainMultipleResult(data);
if (!tmpSelectList.isEmpty()) {
selectList = tmpSelectList;
}
WritableArray imageList = new WritableNativeArray(); WritableArray imageList = new WritableNativeArray();
boolean enableBase64 = cameraOptions.getBoolean("enableBase64"); boolean enableBase64 = cameraOptions.getBoolean("enableBase64");
for (LocalMedia media : selectList) { for (LocalMedia media : tmpSelectList) {
WritableMap aImage = new WritableNativeMap(); WritableMap aImage = new WritableNativeMap();
BitmapFactory.Options options = new BitmapFactory.Options(); BitmapFactory.Options options = new BitmapFactory.Options();
...@@ -238,7 +254,7 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -238,7 +254,7 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
imageList.pushMap(aImage); imageList.pushMap(aImage);
} }
if (selectList.isEmpty()) { if (tmpSelectList.isEmpty()) {
invokeError(); invokeError();
} else { } else {
invokeSuccessWithResult(imageList); invokeSuccessWithResult(imageList);
...@@ -259,7 +275,7 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -259,7 +275,7 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
byte[] encode = Base64.encode(bytes,Base64.DEFAULT); byte[] encode = Base64.encode(bytes,Base64.DEFAULT);
String encodeString = new String(encode); String encodeString = new String(encode);
return encodeString; return "data:image/jpeg;base64," + encodeString;
} }
/** /**
......
...@@ -103,5 +103,13 @@ export default { ...@@ -103,5 +103,13 @@ export default {
*/ */
deleteCache() { deleteCache() {
RNSyanImagePicker.deleteCache() RNSyanImagePicker.deleteCache()
},
/**
* 移除选中的图片
* @param {Number} index 要移除的图片下标
*/
removePhotoAtIndex(index) {
RNSyanImagePicker.removePhotoAtIndex(index)
} }
}; };
...@@ -22,10 +22,26 @@ ...@@ -22,10 +22,26 @@
保存回调的callback 保存回调的callback
*/ */
@property (nonatomic, copy) RCTResponseSenderBlock callback; @property (nonatomic, copy) RCTResponseSenderBlock callback;
/**
保存选中的图片数组
*/
@property (nonatomic, strong) NSMutableArray *selectedAssets;
@end @end
@implementation RNSyanImagePicker @implementation RNSyanImagePicker
- (instancetype)init {
self = [super init];
if (self) {
_selectedAssets = [NSMutableArray array];
}
return self;
}
- (void)dealloc {
_selectedAssets = nil;
}
RCT_EXPORT_MODULE() RCT_EXPORT_MODULE()
RCT_EXPORT_METHOD(showImagePicker:(NSDictionary *)options RCT_EXPORT_METHOD(showImagePicker:(NSDictionary *)options
...@@ -61,6 +77,12 @@ RCT_EXPORT_METHOD(deleteCache) { ...@@ -61,6 +77,12 @@ RCT_EXPORT_METHOD(deleteCache) {
[fileManager removeItemAtPath: [NSString stringWithFormat:@"%@ImageCaches", NSTemporaryDirectory()] error:nil]; [fileManager removeItemAtPath: [NSString stringWithFormat:@"%@ImageCaches", NSTemporaryDirectory()] error:nil];
} }
RCT_EXPORT_METHOD(removePhotoAtIndex:(NSInteger)index) {
if (self.selectedAssets && self.selectedAssets.count > index) {
[self.selectedAssets removeObjectAtIndex:index];
}
}
- (void)openImagePicker { - (void)openImagePicker {
// 照片最大可选张数 // 照片最大可选张数
NSInteger imageCount = [self.cameraOptions sy_integerForKey:@"imageCount"]; NSInteger imageCount = [self.cameraOptions sy_integerForKey:@"imageCount"];
...@@ -82,6 +104,7 @@ RCT_EXPORT_METHOD(deleteCache) { ...@@ -82,6 +104,7 @@ RCT_EXPORT_METHOD(deleteCache) {
imagePickerVc.allowPickingVideo = NO; // 不允许视频 imagePickerVc.allowPickingVideo = NO; // 不允许视频
imagePickerVc.allowPickingOriginalPhoto = NO; // 允许原图 imagePickerVc.allowPickingOriginalPhoto = NO; // 允许原图
imagePickerVc.allowCrop = isCrop; // 裁剪 imagePickerVc.allowCrop = isCrop; // 裁剪
imagePickerVc.selectedAssets = self.selectedAssets; // 当前已选中的图片
if (imageCount == 1) { if (imageCount == 1) {
// 单选模式 // 单选模式
...@@ -99,9 +122,10 @@ RCT_EXPORT_METHOD(deleteCache) { ...@@ -99,9 +122,10 @@ RCT_EXPORT_METHOD(deleteCache) {
} }
} }
} }
__block TZImagePickerController *weakPicker = imagePickerVc; __block TZImagePickerController *weakPicker = imagePickerVc;
[imagePickerVc setDidFinishPickingPhotosWithInfosHandle:^(NSArray<UIImage *> *photos,NSArray *assets,BOOL isSelectOriginalPhoto,NSArray<NSDictionary *> *infos) { [imagePickerVc setDidFinishPickingPhotosWithInfosHandle:^(NSArray<UIImage *> *photos,NSArray *assets,BOOL isSelectOriginalPhoto,NSArray<NSDictionary *> *infos) {
self.selectedAssets = [NSMutableArray arrayWithArray:assets];
NSMutableArray *selectedPhotos = [NSMutableArray array]; NSMutableArray *selectedPhotos = [NSMutableArray array];
[weakPicker showProgressHUD]; [weakPicker showProgressHUD];
if (imageCount == 1 && isCrop) { if (imageCount == 1 && isCrop) {
...@@ -114,11 +138,11 @@ RCT_EXPORT_METHOD(deleteCache) { ...@@ -114,11 +138,11 @@ RCT_EXPORT_METHOD(deleteCache) {
[self invokeSuccessWithResult:selectedPhotos]; [self invokeSuccessWithResult:selectedPhotos];
[weakPicker hideProgressHUD]; [weakPicker hideProgressHUD];
}]; }];
[imagePickerVc setImagePickerControllerDidCancelHandle:^{ [imagePickerVc setImagePickerControllerDidCancelHandle:^{
[self invokeError]; [self invokeError];
}]; }];
[[self topViewController] presentViewController:imagePickerVc animated:YES completion:nil]; [[self topViewController] presentViewController:imagePickerVc animated:YES completion:nil];
} }
...@@ -191,12 +215,12 @@ RCT_EXPORT_METHOD(deleteCache) { ...@@ -191,12 +215,12 @@ RCT_EXPORT_METHOD(deleteCache) {
[picker dismissViewControllerAnimated:YES completion:nil]; [picker dismissViewControllerAnimated:YES completion:nil];
NSString *type = [info objectForKey:UIImagePickerControllerMediaType]; NSString *type = [info objectForKey:UIImagePickerControllerMediaType];
if ([type isEqualToString:@"public.image"]) { if ([type isEqualToString:@"public.image"]) {
TZImagePickerController *tzImagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:1 delegate:nil]; TZImagePickerController *tzImagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:1 delegate:nil];
tzImagePickerVc.sortAscendingByModificationDate = NO; tzImagePickerVc.sortAscendingByModificationDate = NO;
[tzImagePickerVc showProgressHUD]; [tzImagePickerVc showProgressHUD];
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// save photo and get asset / 保存图片,获取到asset // save photo and get asset / 保存图片,获取到asset
[[TZImageManager manager] savePhotoWithImage:image location:NULL completion:^(NSError *error){ [[TZImageManager manager] savePhotoWithImage:image location:NULL completion:^(NSError *error){
if (error) { if (error) {
...@@ -206,7 +230,7 @@ RCT_EXPORT_METHOD(deleteCache) { ...@@ -206,7 +230,7 @@ RCT_EXPORT_METHOD(deleteCache) {
[[TZImageManager manager] getCameraRollAlbum:NO allowPickingImage:YES needFetchAssets:YES completion:^(TZAlbumModel *model) { [[TZImageManager manager] getCameraRollAlbum:NO allowPickingImage:YES needFetchAssets:YES completion:^(TZAlbumModel *model) {
[[TZImageManager manager] getAssetsFromFetchResult:model.result allowPickingVideo:NO allowPickingImage:YES completion:^(NSArray<TZAssetModel *> *models) { [[TZImageManager manager] getAssetsFromFetchResult:model.result allowPickingVideo:NO allowPickingImage:YES completion:^(NSArray<TZAssetModel *> *models) {
[tzImagePickerVc hideProgressHUD]; [tzImagePickerVc hideProgressHUD];
TZAssetModel *assetModel = [models firstObject]; TZAssetModel *assetModel = [models firstObject];
BOOL isCrop = [self.cameraOptions sy_boolForKey:@"isCrop"]; BOOL isCrop = [self.cameraOptions sy_boolForKey:@"isCrop"];
BOOL showCropCircle = [self.cameraOptions sy_boolForKey:@"showCropCircle"]; BOOL showCropCircle = [self.cameraOptions sy_boolForKey:@"showCropCircle"];
...@@ -214,7 +238,7 @@ RCT_EXPORT_METHOD(deleteCache) { ...@@ -214,7 +238,7 @@ RCT_EXPORT_METHOD(deleteCache) {
NSInteger CropH = [self.cameraOptions sy_integerForKey:@"CropH"]; NSInteger CropH = [self.cameraOptions sy_integerForKey:@"CropH"];
NSInteger circleCropRadius = [self.cameraOptions sy_integerForKey:@"circleCropRadius"]; NSInteger circleCropRadius = [self.cameraOptions sy_integerForKey:@"circleCropRadius"];
NSInteger quality = [self.cameraOptions sy_integerForKey:@"quality"]; NSInteger quality = [self.cameraOptions sy_integerForKey:@"quality"];
if (isCrop) { if (isCrop) {
TZImagePickerController *imagePicker = [[TZImagePickerController alloc] initCropTypeWithAsset:assetModel.asset photo:image completion:^(UIImage *cropImage, id asset) { TZImagePickerController *imagePicker = [[TZImagePickerController alloc] initCropTypeWithAsset:assetModel.asset photo:image completion:^(UIImage *cropImage, id asset) {
[self invokeSuccessWithResult:@[[self handleImageData:cropImage quality:quality]]]; [self invokeSuccessWithResult:@[[self handleImageData:cropImage quality:quality]]];
...@@ -258,12 +282,12 @@ RCT_EXPORT_METHOD(deleteCache) { ...@@ -258,12 +282,12 @@ RCT_EXPORT_METHOD(deleteCache) {
- (NSDictionary *)handleImageData:(UIImage *) image quality:(NSInteger)quality { - (NSDictionary *)handleImageData:(UIImage *) image quality:(NSInteger)quality {
NSMutableDictionary *photo = [NSMutableDictionary dictionary]; NSMutableDictionary *photo = [NSMutableDictionary dictionary];
NSData *imageData = UIImageJPEGRepresentation(image, quality * 1.0 / 100); NSData *imageData = UIImageJPEGRepresentation(image, quality * 1.0 / 100);
// 剪切图片并放在tmp中 // 剪切图片并放在tmp中
photo[@"width"] = @(image.size.width); photo[@"width"] = @(image.size.width);
photo[@"height"] = @(image.size.height); photo[@"height"] = @(image.size.height);
photo[@"size"] = @(imageData.length); photo[@"size"] = @(imageData.length);
NSString *fileName = [NSString stringWithFormat:@"%@.jpg", [[NSUUID UUID] UUIDString]]; NSString *fileName = [NSString stringWithFormat:@"%@.jpg", [[NSUUID UUID] UUIDString]];
[self createDir]; [self createDir];
NSString *filePath = [NSString stringWithFormat:@"%@ImageCaches/%@", NSTemporaryDirectory(), fileName]; NSString *filePath = [NSString stringWithFormat:@"%@ImageCaches/%@", NSTemporaryDirectory(), fileName];
...@@ -272,7 +296,7 @@ RCT_EXPORT_METHOD(deleteCache) { ...@@ -272,7 +296,7 @@ RCT_EXPORT_METHOD(deleteCache) {
} else { } else {
NSLog(@"保存压缩图片失败%@", filePath); NSLog(@"保存压缩图片失败%@", filePath);
} }
if ([self.cameraOptions sy_boolForKey:@"enableBase64"]) { if ([self.cameraOptions sy_boolForKey:@"enableBase64"]) {
photo[@"base64"] = [imageData base64EncodedStringWithOptions:0]; photo[@"base64"] = [imageData base64EncodedStringWithOptions:0];
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment