Commit b1f06c98 authored by 少言's avatar 少言

change 优化安卓base64

parent 98e93870
...@@ -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;
...@@ -93,8 +96,7 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -93,8 +96,7 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
/** /**
* 移除选中的图片 * 移除选中的图片
* * index 要移除的图片下标
* @param {int} index 要移除的图片下标
*/ */
@ReactMethod @ReactMethod
public void removePhotoAtIndex(int index) { public void removePhotoAtIndex(int index) {
...@@ -143,6 +145,8 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -143,6 +145,8 @@ 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");
int minimumCompressSize = this.cameraOptions.getInt("minimumCompressSize");
int quality = this.cameraOptions.getInt("quality"); int quality = this.cameraOptions.getInt("quality");
int modeValue; int modeValue;
...@@ -159,7 +163,6 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -159,7 +163,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,7 +170,7 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -167,7 +170,7 @@ 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
...@@ -178,15 +181,11 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -178,15 +181,11 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
.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(true) // 裁剪是否可旋转图片 true or false
.scaleEnabled(true)// 裁剪是否可放大缩小图片 true or false .scaleEnabled(true)// 裁剪是否可放大缩小图片 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 +199,8 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -200,6 +199,8 @@ 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");
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,7 +208,7 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -207,7 +208,7 @@ 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
...@@ -221,13 +222,66 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -221,13 +222,66 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
.videoMinSecond(10)// 显示多少秒以内的视频or音频也可适用 int .videoMinSecond(10)// 显示多少秒以内的视频or音频也可适用 int
.recordVideoSecond(60)//视频秒数录制 默认60s 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(true) // 裁剪是否可旋转图片 true or false
.scaleEnabled(true)// 裁剪是否可放大缩小图片 true or false .scaleEnabled(true)// 裁剪是否可放大缩小图片 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) {
...@@ -282,50 +336,7 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -282,50 +336,7 @@ 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));
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()) { if (tmpSelectList.isEmpty()) {
invokeError(); invokeError();
...@@ -334,74 +345,61 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -334,74 +345,61 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
} }
} }
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编码字符串 * 获取图片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; }
}
/**
* 拍摄视频
*/
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
}
/** byte[] bytes;
* 选择视频 byte[] buffer = new byte[8192];
*/ int bytesRead;
private void openVideoPicker() { 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 videoCount = this.cameraOptions.getInt("videoCount"); } catch (IOException e) {
Activity currentActivity = getCurrentActivity(); e.printStackTrace();
PictureSelector.create(currentActivity) }
.openGallery(PictureMimeType.ofVideo())//全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo()、音频.ofAudio() bytes = output.toByteArray();
.selectionMedia(selectList) // 当前已选中的视频 List return "data:image/jpeg;base64," + Base64.encodeToString(bytes, Base64.NO_WRAP);
.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
} }
/** /**
...@@ -429,4 +427,5 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule { ...@@ -429,4 +427,5 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
this.mPickerPromise.reject(SY_SELECT_IMAGE_FAILED_CODE, "取消"); this.mPickerPromise.reject(SY_SELECT_IMAGE_FAILED_CODE, "取消");
} }
} }
} }
...@@ -21,6 +21,8 @@ const defaultOptions = { ...@@ -21,6 +21,8 @@ const defaultOptions = {
circleCropRadius: ~~(width / 4), // 圆形裁剪半径,默认屏幕宽度一半 circleCropRadius: ~~(width / 4), // 圆形裁剪半径,默认屏幕宽度一半
showCropFrame: true, // 是否显示裁剪区域,默认true showCropFrame: true, // 是否显示裁剪区域,默认true
showCropGrid: false, // 是否隐藏裁剪区域网格,默认false showCropGrid: false, // 是否隐藏裁剪区域网格,默认false
compress: true,
minimumCompressSize: 100, // 小于100kb的图片不压缩
quality: 90, // 压缩质量 quality: 90, // 压缩质量
enableBase64: false, // 是否返回base64编码,默认不返回 enableBase64: false, // 是否返回base64编码,默认不返回
allowPickingOriginalPhoto: false, allowPickingOriginalPhoto: false,
......
{ {
"name": "react-native-syan-image-picker", "name": "react-native-syan-image-picker",
"version": "0.3.4", "version": "0.3.5",
"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