Unverified Commit 6f2108ee authored by jearyVon's avatar jearyVon Committed by GitHub

Merge pull request #1 from jearyvon/fix-png-bug

Fix png bug
parents bc2fe84f 46a7ab8e
...@@ -118,6 +118,33 @@ android { ...@@ -118,6 +118,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 是否成功
2. 使用 Android Studio 查看 `MainApplication.java` 文件是否添加 `new RNSyanImagePickerPackage()` 2. 使用 Android Studio 查看 `MainApplication.java` 文件是否添加 `new RNSyanImagePickerPackage()`
...@@ -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,30 +222,80 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -207,30 +222,80 @@ 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 void openVideo() {
int quality = this.cameraOptions.getInt("quality");
int MaxSecond = this.cameraOptions.getInt("MaxSecond");
int MinSecond = this.cameraOptions.getInt("MinSecond");
int recordVideoSecond = this.cameraOptions.getInt("recordVideoSecond");
int imageCount = this.cameraOptions.getInt("imageCount");
Activity currentActivity = getCurrentActivity();
PictureSelector.create(currentActivity)
.openCamera(PictureMimeType.ofVideo())//全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo()、音频.ofAudio()
.selectionMedia(selectList) // 当前已选中的图片 List
.openClickSound(false)// 是否开启点击声音 true or false
.maxSelectNum(imageCount)// 最大图片选择数量 int
.minSelectNum(0)// 最小选择数量 int
.imageSpanCount(4)// 每行显示个数 int
.selectionMode(PictureConfig.MULTIPLE)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE
.previewVideo(true)// 是否可预览视频 true or false
.videoQuality(quality)// 视频录制质量 0 or 1 int
.videoMaxSecond(MaxSecond)// 显示多少秒以内的视频or音频也可适用 int
.videoMinSecond(MinSecond)// 显示多少秒以内的视频or音频也可适用 int
.recordVideoSecond(recordVideoSecond)//视频秒数录制 默认60s int
.forResult(PictureConfig.REQUEST_CAMERA);//结果回调onActivityResult code
}
/**
* 选择视频
*/
private void openVideoPicker() {
int quality = this.cameraOptions.getInt("quality");
int MaxSecond = this.cameraOptions.getInt("MaxSecond");
int MinSecond = this.cameraOptions.getInt("MinSecond");
int recordVideoSecond = this.cameraOptions.getInt("recordVideoSecond");
int videoCount = this.cameraOptions.getInt("videoCount");
Activity currentActivity = getCurrentActivity();
PictureSelector.create(currentActivity)
.openGallery(PictureMimeType.ofVideo())//全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo()、音频.ofAudio()
.selectionMedia(selectList) // 当前已选中的视频 List
.openClickSound(false)// 是否开启点击声音 true or false
.isCamera(false)// 是否显示拍照按钮 true or false
.maxSelectNum(videoCount)// 最大视频选择数量 int
.minSelectNum(1)// 最小选择数量 int
.imageSpanCount(4)// 每行显示个数 int
.selectionMode(PictureConfig.MULTIPLE)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE
.previewVideo(true)// 是否可预览视频 true or false
.videoQuality(quality)// 视频录制质量 0 or 1 int
.videoMaxSecond(MaxSecond)// 显示多少秒以内的视频or音频也可适用 int
.videoMinSecond(MinSecond)// 显示多少秒以内的视频or音频也可适用 int
.recordVideoSecond(recordVideoSecond)//视频秒数录制 默认60s int
.forResult(PictureConfig.REQUEST_CAMERA);//结果回调onActivityResult code
}
private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() { private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {
@Override @Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, final Intent data) { public void onActivityResult(Activity activity, int requestCode, int resultCode, final Intent data) {
if (resultCode == -1) {
if (requestCode == PictureConfig.CHOOSE_REQUEST) { if (requestCode == PictureConfig.CHOOSE_REQUEST) {
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
...@@ -241,13 +306,17 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -241,13 +306,17 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
} else if (requestCode == PictureConfig.REQUEST_CAMERA) { } else if (requestCode == PictureConfig.REQUEST_CAMERA) {
onGetVideoResult(data); onGetVideoResult(data);
} }
} else {
invokeError(resultCode);
}
} }
}; };
private void onGetVideoResult(Intent data) { private void onGetVideoResult(Intent data) {
List<LocalMedia> mVideoSelectList = PictureSelector.obtainMultipleResult(data); List<LocalMedia> mVideoSelectList = PictureSelector.obtainMultipleResult(data);
boolean isRecordSelectedV = cameraOptions.getBoolean("isRecordSelected"); boolean isRecordSelected = cameraOptions.getBoolean("isRecordSelected");
if (!mVideoSelectList.isEmpty() && isRecordSelectedV) { if (!mVideoSelectList.isEmpty() && isRecordSelected) {
selectList = mVideoSelectList; selectList = mVideoSelectList;
} }
WritableArray videoList = new WritableNativeArray(); WritableArray videoList = new WritableNativeArray();
...@@ -255,21 +324,17 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -255,21 +324,17 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
if (TextUtils.isEmpty(media.getPath())){ if (TextUtils.isEmpty(media.getPath())){
continue; continue;
} }
WritableMap avideo = new WritableNativeMap(); WritableMap videoMap = new WritableNativeMap();
avideo.putString("size", new File(media.getPath()).length() + ""); videoMap.putString("size", new File(media.getPath()).length() + "");
avideo.putString("duration", media.getDuration() + ""); videoMap.putString("duration", media.getDuration() + "");
avideo.putString("fileName", new File(media.getPath()).getName()); videoMap.putString("fileName", new File(media.getPath()).getName());
avideo.putString("uri", "file://" + media.getPath()); videoMap.putString("uri", "file://" + media.getPath());
avideo.putString("type", "video"); videoMap.putString("type", "video");
videoList.pushMap(avideo); videoList.pushMap(videoMap);
} }
if (mVideoSelectList.isEmpty()) {
invokeError();
} else {
invokeSuccessWithResult(videoList); invokeSuccessWithResult(videoList);
} }
}
private void onGetResult(Intent data) { private void onGetResult(Intent data) {
List<LocalMedia> tmpSelectList = PictureSelector.obtainMultipleResult(data); List<LocalMedia> tmpSelectList = PictureSelector.obtainMultipleResult(data);
...@@ -282,126 +347,66 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -282,126 +347,66 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
boolean enableBase64 = cameraOptions.getBoolean("enableBase64"); boolean enableBase64 = cameraOptions.getBoolean("enableBase64");
for (LocalMedia media : tmpSelectList) { for (LocalMedia media : tmpSelectList) {
WritableMap aImage = new WritableNativeMap(); 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(); BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; options.inJustDecodeBounds = true;
if (!media.isCompressed()) { BitmapFactory.decodeFile(path, options);
BitmapFactory.decodeFile(media.getPath(), options); imageMap.putDouble("width", options.outWidth);
aImage.putDouble("width", options.outWidth); imageMap.putDouble("height", options.outHeight);
aImage.putDouble("height", options.outHeight); imageMap.putString("type", "image");
aImage.putString("type", "image"); imageMap.putString("uri", "file://" + path);
aImage.putString("uri", "file://" + media.getPath()); imageMap.putInt("size", (int) new File(path).length());
//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) { if (enableBase64) {
String encodeString = getBase64EncodeString(bitmap); String encodeString = getBase64StringFromFile(path);
aImage.putString("base64", encodeString); imageMap.putString("base64", encodeString);
}
} }
if (media.isCut()) { if (media.isCut()) {
aImage.putString("original_uri", "file://" + media.getCutPath()); imageMap.putString("original_uri", "file://" + media.getCutPath());
} else {
aImage.putString("original_uri", "file://" + media.getPath());
}
imageList.pushMap(aImage);
}
if (tmpSelectList.isEmpty()) {
invokeError();
} else { } else {
invokeSuccessWithResult(imageList); imageMap.putString("original_uri", "file://" + media.getPath());
} }
return imageMap;
} }
/** /**
* 获取图片base64编码字符串 * 获取图片base64编码字符串
* *
* @param bitmap Bitmap对象 * @param absoluteFilePath 文件路径
* @return base64字符串 * @return base64字符串
*/ */
private String getBase64EncodeString(Bitmap bitmap) { private String getBase64StringFromFile(String absoluteFilePath) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); InputStream inputStream;
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); try {
byte[] bytes = baos.toByteArray(); inputStream = new FileInputStream(new File(absoluteFilePath));
} catch (FileNotFoundException e) {
byte[] encode = Base64.encode(bytes, Base64.DEFAULT); e.printStackTrace();
String encodeString = new String(encode); return null;
return "data:image/jpeg;base64," + encodeString;
} }
/** byte[] bytes;
* 拍摄视频 byte[] buffer = new byte[8192];
*/ int bytesRead;
private void openVideo() { ByteArrayOutputStream output = new ByteArrayOutputStream();
int quality = this.cameraOptions.getInt("quality"); try {
int MaxSecond = this.cameraOptions.getInt("MaxSecond"); while ((bytesRead = inputStream.read(buffer)) != -1) {
int MinSecond = this.cameraOptions.getInt("MinSecond"); output.write(buffer, 0, bytesRead);
int recordVideoSecond = this.cameraOptions.getInt("recordVideoSecond");
int imageCount = this.cameraOptions.getInt("imageCount");
Activity currentActivity = getCurrentActivity();
PictureSelector.create(currentActivity)
.openCamera(PictureMimeType.ofVideo())//全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo()、音频.ofAudio()
.selectionMedia(selectList) // 当前已选中的图片 List
.openClickSound(false)// 是否开启点击声音 true or false
.maxSelectNum(imageCount)// 最大图片选择数量 int
.minSelectNum(0)// 最小选择数量 int
.imageSpanCount(4)// 每行显示个数 int
.selectionMode(PictureConfig.MULTIPLE)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE
.previewVideo(true)// 是否可预览视频 true or false
.videoQuality(quality)// 视频录制质量 0 or 1 int
.videoMaxSecond(MaxSecond)// 显示多少秒以内的视频or音频也可适用 int
.videoMinSecond(MinSecond)// 显示多少秒以内的视频or音频也可适用 int
.recordVideoSecond(recordVideoSecond)//视频秒数录制 默认60s int
.forResult(PictureConfig.REQUEST_CAMERA);//结果回调onActivityResult code
} }
} catch (IOException e) {
/** e.printStackTrace();
* 选择视频 }
*/ bytes = output.toByteArray();
private void openVideoPicker() { return "data:image/jpeg;base64," + Base64.encodeToString(bytes, Base64.NO_WRAP);
int quality = this.cameraOptions.getInt("quality");
int MaxSecond = this.cameraOptions.getInt("MaxSecond");
int MinSecond = this.cameraOptions.getInt("MinSecond");
int recordVideoSecond = this.cameraOptions.getInt("recordVideoSecond");
int videoCount = this.cameraOptions.getInt("videoCount");
Activity currentActivity = getCurrentActivity();
PictureSelector.create(currentActivity)
.openGallery(PictureMimeType.ofVideo())//全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo()、音频.ofAudio()
.selectionMedia(selectList) // 当前已选中的视频 List
.openClickSound(false)// 是否开启点击声音 true or false
.isCamera(false)// 是否显示拍照按钮 true or false
.maxSelectNum(videoCount)// 最大视频选择数量 int
.minSelectNum(1)// 最小选择数量 int
.imageSpanCount(4)// 每行显示个数 int
.selectionMode(PictureConfig.MULTIPLE)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE
// TODO: 2019/2/14 需要根据用户设置来决定是否展示video
.previewVideo(true)// 是否可预览视频 true or false
.videoQuality(quality)// 视频录制质量 0 or 1 int
.videoMaxSecond(MaxSecond)// 显示多少秒以内的视频or音频也可适用 int
.videoMinSecond(MinSecond)// 显示多少秒以内的视频or音频也可适用 int
.recordVideoSecond(recordVideoSecond)//视频秒数录制 默认60s int
.forResult(PictureConfig.REQUEST_CAMERA);//结果回调onActivityResult code
} }
/** /**
...@@ -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