Commit 46a7ab8e authored by jearyVon's avatar jearyVon

Merge branch 'master' of https://github.com/syanbo/react-native-syan-image-picker into fix-png-bug

parents bc2fe84f 0265c1ae
...@@ -117,6 +117,33 @@ android { ...@@ -117,6 +117,33 @@ android {
... ...
} }
``` ```
##### 4、拍照前动态获取权限
```js
requestPermission = async () => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
title: '申请读写手机存储权限',
message:
'一个很牛逼的应用想借用你的摄像头,' +
'然后你就可以拍出酷炫的皂片啦。',
buttonNeutral: '等会再问我',
buttonNegative: '不行',
buttonPositive: '好吧',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('现在你获得摄像头权限了');
} else {
console.log('用户并不给你');
}
} catch (err) {
console.warn(err);
}
};
```
### 注意安装运行报错 ### 注意安装运行报错
1. 检查自动 link 是否成功 1. 检查自动 link 是否成功
...@@ -135,13 +162,16 @@ android { ...@@ -135,13 +162,16 @@ android {
### Android ### Android
1. Open up `android/app/src/main/java/[...]/MainApplication.java` 1. Open up `android/app/src/main/java/[...]/MainApplication.java`
- Add `import com.reactlibrary.RNSyanImagePickerPackage;` to the imports at the top of the file - Add `import com.reactlibrary.RNSyanImagePickerPackage;` to the imports at the top of the file
- Add `new RNSyanImagePickerPackage()` to the list returned by the `getPackages()` method - Add `new RNSyanImagePickerPackage()` to the list returned by the `getPackages()` method
2. Append the following lines to `android/settings.gradle`: 2. Append the following lines to `android/settings.gradle`:
```gradle ```gradle
include ':react-native-syan-image-picker' include ':react-native-syan-image-picker'
project(':react-native-syan-image-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-syan-image-picker/android') project(':react-native-syan-image-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-syan-image-picker/android')
``` ```
3. Insert the following lines inside the dependencies block in `android/app/build.gradle`: 3. Insert the following lines inside the dependencies block in `android/app/build.gradle`:
```gradle ```gradle
compile project(':react-native-syan-image-picker') compile project(':react-native-syan-image-picker')
...@@ -167,8 +197,14 @@ showCropCircle | bool | 是 | false | 是否显示圆形裁剪区 ...@@ -167,8 +197,14 @@ showCropCircle | bool | 是 | false | 是否显示圆形裁剪区
circleCropRadius | float | 是 | screenW * 0.5 | 圆形裁剪半径,默认屏幕宽度一半 circleCropRadius | float | 是 | screenW * 0.5 | 圆形裁剪半径,默认屏幕宽度一半
showCropFrame | bool | 是 | true | 是否显示裁剪区域 showCropFrame | bool | 是 | true | 是否显示裁剪区域
showCropGrid | bool | 是 | false | 是否隐藏裁剪区域网格 showCropGrid | bool | 是 | false | 是否隐藏裁剪区域网格
quality | int | 是 | 90 | 压缩质量 quality | int | 是 | 90 | 压缩质量(安卓无效,固定鲁班压缩)
minimumCompressSize | int | 是 | 100 | 小于100kb的图片不压缩(Android)
enableBase64 | bool | 是 | false | 是否返回base64编码,默认不返回 enableBase64 | bool | 是 | false | 是否返回base64编码,默认不返回
freeStyleCropEnabled | bool | 是 | false | 裁剪框是否可拖拽(Android)
rotateEnabled | bool | 是 | true | 裁剪是否可旋转图片(Android)
scaleEnabled | bool | 是 | true | 裁剪是否可放大缩小图片(Android)
## 返回结果说明 ## 返回结果说明
以 `Callback` 形式调用时,返回的第一个参数为错误对象,第二个才是图片数组: 以 `Callback` 形式调用时,返回的第一个参数为错误对象,第二个才是图片数组:
...@@ -253,7 +289,27 @@ STImagePicke.removeAllPhoto() ...@@ -253,7 +289,27 @@ STImagePicke.removeAllPhoto()
``` ```
### 调用相机 ### 调用相机
相机功能调用 `openCamera` 方法,一样支持 Callback 和 Promise 两种形式,结果参数也保持一致。 相机功能调用方法,一样支持 Callback 和 Promise 两种形式,结果参数也保持一致。
```javascript
//Callback方式
SyanImagePicker.openCamera(options, (err, photos) => {
if (err) {
// 取消选择
return;
}
// 选择成功,渲染图片
// ...
})
//Promise方式
SYImagePicker.asyncOpenCamera(options)
.then(()=>{
...
})
.catch(()=>{
...
})
```
### 删除缓存 ### 删除缓存
```javascript ```javascript
......
...@@ -3,7 +3,6 @@ package com.syanpicker; ...@@ -3,7 +3,6 @@ package com.syanpicker;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Base64; import android.util.Base64;
...@@ -29,6 +28,10 @@ import com.luck.picture.lib.tools.PictureFileUtils; ...@@ -29,6 +28,10 @@ import com.luck.picture.lib.tools.PictureFileUtils;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
...@@ -81,6 +84,14 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -81,6 +84,14 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
this.openCamera(); this.openCamera();
} }
@ReactMethod
public void asyncOpenCamera(ReadableMap options, Promise promise) {
this.cameraOptions = options;
this.mPickerCallback = null;
this.mPickerPromise = promise;
this.openCamera();
}
/** /**
* 缓存清除 * 缓存清除
* 包括裁剪和压缩后的缓存,要在上传成功后调用,注意:需要系统sd卡权限 * 包括裁剪和压缩后的缓存,要在上传成功后调用,注意:需要系统sd卡权限
...@@ -93,8 +104,7 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -93,8 +104,7 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
/** /**
* 移除选中的图片 * 移除选中的图片
* * index 要移除的图片下标
* @param {int} index 要移除的图片下标
*/ */
@ReactMethod @ReactMethod
public void removePhotoAtIndex(int index) { public void removePhotoAtIndex(int index) {
...@@ -143,6 +153,11 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -143,6 +153,11 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
boolean showCropCircle = this.cameraOptions.getBoolean("showCropCircle"); boolean showCropCircle = this.cameraOptions.getBoolean("showCropCircle");
boolean showCropFrame = this.cameraOptions.getBoolean("showCropFrame"); boolean showCropFrame = this.cameraOptions.getBoolean("showCropFrame");
boolean showCropGrid = this.cameraOptions.getBoolean("showCropGrid"); boolean showCropGrid = this.cameraOptions.getBoolean("showCropGrid");
boolean compress = this.cameraOptions.getBoolean("compress");
boolean freeStyleCropEnabled = this.cameraOptions.getBoolean("freeStyleCropEnabled");
boolean rotateEnabled = this.cameraOptions.getBoolean("rotateEnabled");
boolean scaleEnabled = this.cameraOptions.getBoolean("scaleEnabled");
int minimumCompressSize = this.cameraOptions.getInt("minimumCompressSize");
int quality = this.cameraOptions.getInt("quality"); int quality = this.cameraOptions.getInt("quality");
int modeValue; int modeValue;
...@@ -159,7 +174,6 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -159,7 +174,6 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
.imageSpanCount(4)// 每行显示个数 int .imageSpanCount(4)// 每行显示个数 int
.selectionMode(modeValue)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE .selectionMode(modeValue)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE
.previewImage(true)// 是否可预览图片 true or false .previewImage(true)// 是否可预览图片 true or false
// TODO: 2019/2/14 需要根据用户设置来决定是否展示video
.previewVideo(false)// 是否可预览视频 true or false .previewVideo(false)// 是否可预览视频 true or false
.enablePreviewAudio(false) // 是否可播放音频 true or false .enablePreviewAudio(false) // 是否可播放音频 true or false
.isCamera(isCamera)// 是否显示拍照按钮 true or false .isCamera(isCamera)// 是否显示拍照按钮 true or false
...@@ -167,26 +181,22 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -167,26 +181,22 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
.isZoomAnim(true)// 图片列表点击 缩放效果 默认true .isZoomAnim(true)// 图片列表点击 缩放效果 默认true
.sizeMultiplier(0.5f)// glide 加载图片大小 0~1之间 如设置 .glideOverride()无效 .sizeMultiplier(0.5f)// glide 加载图片大小 0~1之间 如设置 .glideOverride()无效
.enableCrop(isCrop)// 是否裁剪 true or false .enableCrop(isCrop)// 是否裁剪 true or false
.compress(true)// 是否压缩 true or false .compress(compress)// 是否压缩 true or false
.glideOverride(160, 160)// int glide 加载宽高,越小图片列表越流畅,但会影响列表图片浏览的清晰度 .glideOverride(160, 160)// int glide 加载宽高,越小图片列表越流畅,但会影响列表图片浏览的清晰度
.withAspectRatio(CropW, CropH)// int 裁剪比例 如16:9 3:2 3:4 1:1 可自定义 .withAspectRatio(CropW, CropH)// int 裁剪比例 如16:9 3:2 3:4 1:1 可自定义
.hideBottomControls(isCrop)// 是否显示uCrop工具栏,默认不显示 true or false .hideBottomControls(isCrop)// 是否显示uCrop工具栏,默认不显示 true or false
.isGif(isGif)// 是否显示gif图片 true or false .isGif(isGif)// 是否显示gif图片 true or false
.freeStyleCropEnabled(true)// 裁剪框是否可拖拽 true or false .freeStyleCropEnabled(freeStyleCropEnabled)// 裁剪框是否可拖拽 true or false
.circleDimmedLayer(showCropCircle)// 是否圆形裁剪 true or false .circleDimmedLayer(showCropCircle)// 是否圆形裁剪 true or false
.showCropFrame(showCropFrame)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false true or false .showCropFrame(showCropFrame)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false true or false
.showCropGrid(showCropGrid)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false .showCropGrid(showCropGrid)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false
.openClickSound(false)// 是否开启点击声音 true or false .openClickSound(false)// 是否开启点击声音 true or false
.cropCompressQuality(quality)// 裁剪压缩质量 默认90 int .cropCompressQuality(quality)// 裁剪压缩质量 默认90 int
.minimumCompressSize(100)// 小于100kb的图片不压缩 .minimumCompressSize(minimumCompressSize)// 小于100kb的图片不压缩
.synOrAsy(true)//同步true或异步false 压缩 默认同步 .synOrAsy(true)//同步true或异步false 压缩 默认同步
.rotateEnabled(true) // 裁剪是否可旋转图片 true or false .rotateEnabled(rotateEnabled) // 裁剪是否可旋转图片 true or false
.scaleEnabled(true)// 裁剪是否可放大缩小图片 true or false .scaleEnabled(scaleEnabled)// 裁剪是否可放大缩小图片 true or false
.selectionMedia(selectList) // 当前已选中的图片 List .selectionMedia(selectList) // 当前已选中的图片 List
//.videoQuality(0)// 视频录制质量 0 or 1 int
//.videoMaxSecond(15)// 显示多少秒以内的视频or音频也可适用 int
//.videoMinSecond(10)// 显示多少秒以内的视频or音频也可适用 int
//.recordVideoSecond(60)//视频秒数录制 默认60s int
.forResult(PictureConfig.CHOOSE_REQUEST);//结果回调onActivityResult code .forResult(PictureConfig.CHOOSE_REQUEST);//结果回调onActivityResult code
} }
...@@ -200,6 +210,11 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -200,6 +210,11 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
boolean showCropCircle = this.cameraOptions.getBoolean("showCropCircle"); boolean showCropCircle = this.cameraOptions.getBoolean("showCropCircle");
boolean showCropFrame = this.cameraOptions.getBoolean("showCropFrame"); boolean showCropFrame = this.cameraOptions.getBoolean("showCropFrame");
boolean showCropGrid = this.cameraOptions.getBoolean("showCropGrid"); boolean showCropGrid = this.cameraOptions.getBoolean("showCropGrid");
boolean compress = this.cameraOptions.getBoolean("compress");
boolean freeStyleCropEnabled = this.cameraOptions.getBoolean("freeStyleCropEnabled");
boolean rotateEnabled = this.cameraOptions.getBoolean("rotateEnabled");
boolean scaleEnabled = this.cameraOptions.getBoolean("scaleEnabled");
int minimumCompressSize = this.cameraOptions.getInt("minimumCompressSize");
int quality = this.cameraOptions.getInt("quality"); int quality = this.cameraOptions.getInt("quality");
Activity currentActivity = getCurrentActivity(); Activity currentActivity = getCurrentActivity();
...@@ -207,149 +222,23 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -207,149 +222,23 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
.openCamera(PictureMimeType.ofImage()) .openCamera(PictureMimeType.ofImage())
.imageFormat(PictureMimeType.PNG)// 拍照保存图片格式后缀,默认jpeg .imageFormat(PictureMimeType.PNG)// 拍照保存图片格式后缀,默认jpeg
.enableCrop(isCrop)// 是否裁剪 true or false .enableCrop(isCrop)// 是否裁剪 true or false
.compress(true)// 是否压缩 true or false .compress(compress)// 是否压缩 true or false
.glideOverride(160, 160)// int glide 加载宽高,越小图片列表越流畅,但会影响列表图片浏览的清晰度 .glideOverride(160, 160)// int glide 加载宽高,越小图片列表越流畅,但会影响列表图片浏览的清晰度
.withAspectRatio(CropW, CropH)// int 裁剪比例 如16:9 3:2 3:4 1:1 可自定义 .withAspectRatio(CropW, CropH)// int 裁剪比例 如16:9 3:2 3:4 1:1 可自定义
.hideBottomControls(isCrop)// 是否显示uCrop工具栏,默认不显示 true or false .hideBottomControls(isCrop)// 是否显示uCrop工具栏,默认不显示 true or false
.freeStyleCropEnabled(true)// 裁剪框是否可拖拽 true or false .freeStyleCropEnabled(freeStyleCropEnabled)// 裁剪框是否可拖拽 true or false
.circleDimmedLayer(showCropCircle)// 是否圆形裁剪 true or false .circleDimmedLayer(showCropCircle)// 是否圆形裁剪 true or false
.showCropFrame(showCropFrame)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false true or false .showCropFrame(showCropFrame)// 是否显示裁剪矩形边框 圆形裁剪时建议设为false true or false
.showCropGrid(showCropGrid)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false .showCropGrid(showCropGrid)// 是否显示裁剪矩形网格 圆形裁剪时建议设为false true or false
.openClickSound(false)// 是否开启点击声音 true or false .openClickSound(false)// 是否开启点击声音 true or false
.videoQuality(1)// 视频录制质量 0 or 1 int
.videoMaxSecond(15)// 显示多少秒以内的视频or音频也可适用 int
.videoMinSecond(10)// 显示多少秒以内的视频or音频也可适用 int
.recordVideoSecond(60)//视频秒数录制 默认60s int
.cropCompressQuality(quality)// 裁剪压缩质量 默认90 int .cropCompressQuality(quality)// 裁剪压缩质量 默认90 int
.minimumCompressSize(100)// 小于100kb的图片不压缩 .minimumCompressSize(minimumCompressSize)// 小于100kb的图片不压缩
.synOrAsy(true)//同步true或异步false 压缩 默认同步 .synOrAsy(true)//同步true或异步false 压缩 默认同步
.rotateEnabled(true) // 裁剪是否可旋转图片 true or false .rotateEnabled(rotateEnabled) // 裁剪是否可旋转图片 true or false
.scaleEnabled(true)// 裁剪是否可放大缩小图片 true or false .scaleEnabled(scaleEnabled)// 裁剪是否可放大缩小图片 true or false
.forResult(PictureConfig.CHOOSE_REQUEST);//结果回调onActivityResult code .forResult(PictureConfig.CHOOSE_REQUEST);//结果回调onActivityResult code
} }
private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {
@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, final Intent data) {
if (requestCode == PictureConfig.CHOOSE_REQUEST) {
new Thread(new Runnable() {
@Override
public void run() {
onGetResult(data);
}
}).run();
} else if (requestCode == PictureConfig.REQUEST_CAMERA) {
onGetVideoResult(data);
}
}
};
private void onGetVideoResult(Intent data) {
List<LocalMedia> mVideoSelectList = PictureSelector.obtainMultipleResult(data);
boolean isRecordSelectedV = cameraOptions.getBoolean("isRecordSelected");
if (!mVideoSelectList.isEmpty() && isRecordSelectedV) {
selectList = mVideoSelectList;
}
WritableArray videoList = new WritableNativeArray();
for (LocalMedia media : mVideoSelectList) {
if (TextUtils.isEmpty(media.getPath())){
continue;
}
WritableMap avideo = new WritableNativeMap();
avideo.putString("size", new File(media.getPath()).length() + "");
avideo.putString("duration", media.getDuration() + "");
avideo.putString("fileName", new File(media.getPath()).getName());
avideo.putString("uri", "file://" + media.getPath());
avideo.putString("type", "video");
videoList.pushMap(avideo);
}
if (mVideoSelectList.isEmpty()) {
invokeError();
} else {
invokeSuccessWithResult(videoList);
}
}
private void onGetResult(Intent data) {
List<LocalMedia> tmpSelectList = PictureSelector.obtainMultipleResult(data);
boolean isRecordSelected = cameraOptions.getBoolean("isRecordSelected");
if (!tmpSelectList.isEmpty() && isRecordSelected) {
selectList = tmpSelectList;
}
WritableArray imageList = new WritableNativeArray();
boolean enableBase64 = cameraOptions.getBoolean("enableBase64");
for (LocalMedia media : tmpSelectList) {
WritableMap aImage = new WritableNativeMap();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
if (!media.isCompressed()) {
BitmapFactory.decodeFile(media.getPath(), options);
aImage.putDouble("width", options.outWidth);
aImage.putDouble("height", options.outHeight);
aImage.putString("type", "image");
aImage.putString("uri", "file://" + media.getPath());
//decode to bitmap
Bitmap bitmap = BitmapFactory.decodeFile(media.getPath());
aImage.putInt("size", bitmap.getByteCount());
//base64 encode
if (enableBase64) {
String encodeString = getBase64EncodeString(bitmap);
aImage.putString("base64", encodeString);
}
} else {
// 压缩过,取 media.getCompressPath();
BitmapFactory.decodeFile(media.getCompressPath(), options);
aImage.putDouble("width", options.outWidth);
aImage.putDouble("height", options.outHeight);
aImage.putString("type", "image");
aImage.putString("uri", "file://" + media.getCompressPath());
//decode to bitmap
Bitmap bitmap = BitmapFactory.decodeFile(media.getCompressPath());
aImage.putInt("size", bitmap.getByteCount());
//base64 encode
if (enableBase64) {
String encodeString = getBase64EncodeString(bitmap);
aImage.putString("base64", encodeString);
}
}
if (media.isCut()) {
aImage.putString("original_uri", "file://" + media.getCutPath());
} else {
aImage.putString("original_uri", "file://" + media.getPath());
}
imageList.pushMap(aImage);
}
if (tmpSelectList.isEmpty()) {
invokeError();
} else {
invokeSuccessWithResult(imageList);
}
}
/**
* 获取图片base64编码字符串
*
* @param bitmap Bitmap对象
* @return base64字符串
*/
private String getBase64EncodeString(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] bytes = baos.toByteArray();
byte[] encode = Base64.encode(bytes, Base64.DEFAULT);
String encodeString = new String(encode);
return "data:image/jpeg;base64," + encodeString;
}
/** /**
* 拍摄视频 * 拍摄视频
*/ */
...@@ -395,7 +284,6 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -395,7 +284,6 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
.minSelectNum(1)// 最小选择数量 int .minSelectNum(1)// 最小选择数量 int
.imageSpanCount(4)// 每行显示个数 int .imageSpanCount(4)// 每行显示个数 int
.selectionMode(PictureConfig.MULTIPLE)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE .selectionMode(PictureConfig.MULTIPLE)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE
// TODO: 2019/2/14 需要根据用户设置来决定是否展示video
.previewVideo(true)// 是否可预览视频 true or false .previewVideo(true)// 是否可预览视频 true or false
.videoQuality(quality)// 视频录制质量 0 or 1 int .videoQuality(quality)// 视频录制质量 0 or 1 int
.videoMaxSecond(MaxSecond)// 显示多少秒以内的视频or音频也可适用 int .videoMaxSecond(MaxSecond)// 显示多少秒以内的视频or音频也可适用 int
...@@ -404,6 +292,123 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -404,6 +292,123 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
.forResult(PictureConfig.REQUEST_CAMERA);//结果回调onActivityResult code .forResult(PictureConfig.REQUEST_CAMERA);//结果回调onActivityResult code
} }
private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {
@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, final Intent data) {
if (resultCode == -1) {
if (requestCode == PictureConfig.CHOOSE_REQUEST) {
new Thread(new Runnable() {
@Override
public void run() {
onGetResult(data);
}
}).run();
} else if (requestCode == PictureConfig.REQUEST_CAMERA) {
onGetVideoResult(data);
}
} else {
invokeError(resultCode);
}
}
};
private void onGetVideoResult(Intent data) {
List<LocalMedia> mVideoSelectList = PictureSelector.obtainMultipleResult(data);
boolean isRecordSelected = cameraOptions.getBoolean("isRecordSelected");
if (!mVideoSelectList.isEmpty() && isRecordSelected) {
selectList = mVideoSelectList;
}
WritableArray videoList = new WritableNativeArray();
for (LocalMedia media : mVideoSelectList) {
if (TextUtils.isEmpty(media.getPath())){
continue;
}
WritableMap videoMap = new WritableNativeMap();
videoMap.putString("size", new File(media.getPath()).length() + "");
videoMap.putString("duration", media.getDuration() + "");
videoMap.putString("fileName", new File(media.getPath()).getName());
videoMap.putString("uri", "file://" + media.getPath());
videoMap.putString("type", "video");
videoList.pushMap(videoMap);
}
invokeSuccessWithResult(videoList);
}
private void onGetResult(Intent data) {
List<LocalMedia> tmpSelectList = PictureSelector.obtainMultipleResult(data);
boolean isRecordSelected = cameraOptions.getBoolean("isRecordSelected");
if (!tmpSelectList.isEmpty() && isRecordSelected) {
selectList = tmpSelectList;
}
WritableArray imageList = new WritableNativeArray();
boolean enableBase64 = cameraOptions.getBoolean("enableBase64");
for (LocalMedia media : tmpSelectList) {
imageList.pushMap(getImageResult(media, enableBase64));
}
invokeSuccessWithResult(imageList);
}
private WritableMap getImageResult(LocalMedia media, Boolean enableBase64) {
WritableMap imageMap = new WritableNativeMap();
String path = media.getPath();
if (media.isCompressed() || media.isCut()){
path = media.getCompressPath();
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
imageMap.putDouble("width", options.outWidth);
imageMap.putDouble("height", options.outHeight);
imageMap.putString("type", "image");
imageMap.putString("uri", "file://" + path);
imageMap.putInt("size", (int) new File(path).length());
if (enableBase64) {
String encodeString = getBase64StringFromFile(path);
imageMap.putString("base64", encodeString);
}
if (media.isCut()) {
imageMap.putString("original_uri", "file://" + media.getCutPath());
} else {
imageMap.putString("original_uri", "file://" + media.getPath());
}
return imageMap;
}
/**
* 获取图片base64编码字符串
*
* @param absoluteFilePath 文件路径
* @return base64字符串
*/
private String getBase64StringFromFile(String absoluteFilePath) {
InputStream inputStream;
try {
inputStream = new FileInputStream(new File(absoluteFilePath));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
byte[] bytes;
byte[] buffer = new byte[8192];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
while ((bytesRead = inputStream.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
bytes = output.toByteArray();
return "data:image/jpeg;base64," + Base64.encodeToString(bytes, Base64.NO_WRAP);
}
/** /**
* 选择照片成功时触发 * 选择照片成功时触发
* *
...@@ -421,12 +426,17 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -421,12 +426,17 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
/** /**
* 取消选择时触发 * 取消选择时触发
*/ */
private void invokeError() { private void invokeError(int resultCode) {
String message = "取消";
if (resultCode != 0) {
message = String.valueOf(resultCode);
}
if (this.mPickerCallback != null) { if (this.mPickerCallback != null) {
this.mPickerCallback.invoke("取消"); this.mPickerCallback.invoke(message);
this.mPickerCallback = null; this.mPickerCallback = null;
} else if (this.mPickerPromise != null) { } else if (this.mPickerPromise != null) {
this.mPickerPromise.reject(SY_SELECT_IMAGE_FAILED_CODE, "取消"); this.mPickerPromise.reject(SY_SELECT_IMAGE_FAILED_CODE, message);
} }
} }
} }
...@@ -21,6 +21,11 @@ const defaultOptions = { ...@@ -21,6 +21,11 @@ const defaultOptions = {
circleCropRadius: ~~(width / 4), // 圆形裁剪半径,默认屏幕宽度一半 circleCropRadius: ~~(width / 4), // 圆形裁剪半径,默认屏幕宽度一半
showCropFrame: true, // 是否显示裁剪区域,默认true showCropFrame: true, // 是否显示裁剪区域,默认true
showCropGrid: false, // 是否隐藏裁剪区域网格,默认false showCropGrid: false, // 是否隐藏裁剪区域网格,默认false
freeStyleCropEnabled: false, // 裁剪框是否可拖拽
rotateEnabled: true, // 裁剪是否可旋转图片
scaleEnabled: true, // 裁剪是否可放大缩小图片
compress: true,
minimumCompressSize: 100, // 小于100kb的图片不压缩
quality: 90, // 压缩质量 quality: 90, // 压缩质量
enableBase64: false, // 是否返回base64编码,默认不返回 enableBase64: false, // 是否返回base64编码,默认不返回
allowPickingOriginalPhoto: false, allowPickingOriginalPhoto: false,
...@@ -102,6 +107,14 @@ export default { ...@@ -102,6 +107,14 @@ export default {
RNSyanImagePicker.openCamera(optionObj, callback) RNSyanImagePicker.openCamera(optionObj, callback)
}, },
asyncOpenCamera(options) {
const optionObj = {
...defaultOptions,
...options,
};
return RNSyanImagePicker.asyncOpenCamera(optionObj);
},
/** /**
* 清除缓存 * 清除缓存
*/ */
......
...@@ -55,7 +55,7 @@ RCT_EXPORT_METHOD(showImagePicker:(NSDictionary *)options ...@@ -55,7 +55,7 @@ RCT_EXPORT_METHOD(showImagePicker:(NSDictionary *)options
RCT_REMAP_METHOD(asyncShowImagePicker, RCT_REMAP_METHOD(asyncShowImagePicker,
options:(NSDictionary *)options options:(NSDictionary *)options
resolver:(RCTPromiseResolveBlock)resolve showImagePickerResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) { rejecter:(RCTPromiseRejectBlock)reject) {
self.cameraOptions = options; self.cameraOptions = options;
self.resolveBlock = resolve; self.resolveBlock = resolve;
...@@ -72,6 +72,17 @@ RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options callback:(RCTResponseSender ...@@ -72,6 +72,17 @@ RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options callback:(RCTResponseSender
[self takePhoto]; [self takePhoto];
} }
RCT_REMAP_METHOD(asyncOpenCamera,
options:(NSDictionary *)options
openCameraResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
self.cameraOptions = options;
self.resolveBlock = resolve;
self.rejectBlock = reject;
self.callback = nil;
[self takePhoto];
}
RCT_EXPORT_METHOD(deleteCache) { RCT_EXPORT_METHOD(deleteCache) {
NSFileManager *fileManager = [NSFileManager defaultManager]; NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath: [NSString stringWithFormat:@"%@ImageCaches", NSTemporaryDirectory()] error:nil]; [fileManager removeItemAtPath: [NSString stringWithFormat:@"%@ImageCaches", NSTemporaryDirectory()] error:nil];
......
{ {
"name": "react-native-syan-image-picker", "name": "react-native-syan-image-picker",
"version": "0.3.4", "version": "0.3.7",
"description": "React-Native 多图片选择 支持裁剪 压缩", "description": "React-Native 多图片选择 支持裁剪 压缩",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
......
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