大致思路就是creator里面js调用Java和object-c代码,调起系统相机相册,选取图库图片/拍照图片进行裁剪,然后转化为base64字符串,最后通过http post请求上传到服务器。

JavaScript实现部分,调用Java和oc相关接口,传入裁剪参数


// 类型,是否需要裁剪,裁剪尺寸,回调方法
PlatForm.pickImage = function(type,needClip,clipSize,callback){PlatForm.onChoosePhotoCallback = callback;if(needClip == undefined){needClip = false;}var clipX = 0;var clipY = 0;if(clipSize){clipX = clipSize.x;clipY = clipSize.y;}var dict ={needClip:needClip, //1是裁剪,2是不裁剪clipX:clipX, //裁剪x尺寸clipY:clipY, //裁剪y尺寸}if(cc.sys.os === cc.sys.OS_ANDROID){var className = "org/cocos2dx/javascript/AppActivity"var methodName = "pickImage";var methodSignature = "(Ljava/lang/String;)V";if(type == Config.ChoosephotoType.Album){methodName = "useSystemAlbum";}else if(type == Config.ChoosephotoType.Camera){methodName = "useSystemCamera";}var ret = jsb.reflection.callStaticMethod(className,methodName,methodSignature,JSON.stringify(dict));console.log("androidTakePhotoret:",ret)return ret;}else if(cc.sys.os === cc.sys.OS_IOS){console.log("js 请求相册");var ret = null;if(type == Config.ChoosephotoType.Album){ret = jsb.reflection.callStaticMethod("AppController","pickImage:",JSON.stringify(dict));}else if(type == Config.ChoosephotoType.Camera){ret = jsb.reflection.callStaticMethod("AppController","takePhoto:",JSON.stringify(dict));}return ret}
}
  • ios选取图片

1.AppController.h 实现UIImagePickerControllerDelegate接口

@interface AppController : NSObject <UIApplicationDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate>
{
}

2.appController.mm实现js调用接口

选择图库:


// 选择图片
+(void) pickImage:(NSString*) dict{NSData *data = [dict dataUsingEncoding:NSUTF8StringEncoding];NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];NSNumber *needClip = [dictionary objectForKey:@"needClip"];NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];[defaults setObject:needClip forKey:@"needClip"];photoName = [dictionary objectForKey:@"name"];NSLog(@"takePhoto param = %@,%@",needClip,photoName);UIImagePickerController *pickerImage = [[UIImagePickerController alloc] init];if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]){pickerImage.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;pickerImage.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:pickerImage.sourceType];}AppController *pApp = (AppController*)[[UIApplication sharedApplication] delegate];pickerImage.delegate = pApp;pickerImage.allowsEditing = ([needClip intValue] == 1?YES:NO); // 传入是否可以裁剪参数[pApp->_viewController  presentViewController:((UIImagePickerController *)pickerImage) animated:YES completion:nil];
}

选择相机


+(void) takePhoto:(NSString*) dict{NSData *data = [dict dataUsingEncoding:NSUTF8StringEncoding];NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];NSNumber *needClip = [dictionary objectForKey:@"needClip"];photoName = [dictionary objectForKey:@"name"];NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];[defaults setObject:needClip forKey:@"needClip"];NSLog(@"takePhoto param = %@,%@",needClip,photoName);UIImagePickerController *pickerImage = [[UIImagePickerController alloc] init];if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){pickerImage.sourceType = UIImagePickerControllerSourceTypeCamera;pickerImage.cameraDevice = UIImagePickerControllerCameraDeviceFront; //调用前置摄像头,后置摄像头为:UIImagePickerControllerCameraDeviceRear}AppController *pApp = (AppController*)[[UIApplication sharedApplication] delegate];pickerImage.delegate = pApp;pickerImage.allowsEditing = ([needClip intValue] == 1?YES:NO); // 传入是否可以裁剪参数[pApp->_viewController  presentViewController:((UIImagePickerController *)pickerImage) animated:YES completion:nil];
}

3.实现选择照片回调

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)editingInfo
{NSLog(@"imagePickerController info = %@",editingInfo);NSString * fileName = [self getFormatTimeInterval:@".jpg"];NSLog(@"fileName = %@",fileName);NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];NSNumber *needClip = [defaults objectForKey:@"needClip"];//根据键值取出是否需要裁剪NSLog(@"保存的needClip==%@",needClip);if([needClip intValue] == 1){[self saveImage:editingInfo[UIImagePickerControllerEditedImage] WithName:fileName];}else{[self saveImage:editingInfo[UIImagePickerControllerOriginalImage] WithName:fileName];}[[picker presentingViewController] dismissViewControllerAnimated:YES completion:nil];[picker release];
}//使用时间戳作为图片名称
-(NSString*)getFormatTimeInterval:(NSString *) fileType{UInt64 recordTime = [[NSDate date] timeIntervalSince1970] *1000 *1000;NSString * systemCurTime = [NSString stringWithFormat:@"%qu%@",recordTime,fileType];return systemCurTime;
}

4.保存照片并转化为base64字符串,这里是上传头像,避免照片过大,压缩为0.3倍,其他场景可酌情修改倍数。最后调用js代码传递保存图片路径和base64字符串。

- (void)saveImage:(UIImage *)tempImage WithName:(NSString *)imageName
{NSData* imageData = UIImagePNGRepresentation(tempImage);NSString* documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];NSString* totalPath = [documentPath stringByAppendingPathComponent:imageName];//保存到 document[imageData writeToFile:totalPath atomically:NO];NSString *base64Image = [self imageToString:tempImage];NSLog(@"保存图片完整路径=%@",totalPath);NSLog(@"保存图片document路径=%@",documentPath);NSLog(@"图片转化为base64:%@",base64Image);NSString *execStr = [NSString stringWithFormat:@"%@('%@','%@')", @"PlatForm.onPickImageResult",totalPath,base64Image];NSLog(@"调用js语句::%@",execStr);se::ScriptEngine::getInstance()->evalString([execStr UTF8String]);
}//图片转base64
- (NSString *)imageToString:(UIImage *)image {NSData *imagedata = UIImageJPEGRepresentation(image,0.3); //压缩到0.3倍NSString *image64 = [imagedata base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn];return image64;
}

最后,不要忘记在info.plist添加调用相册相机权限

  • Android选取图片

1.AndroidManifest.xml增加读写权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />

2.AppActivity实现js调用Java接口

调用相册,动态获取权限

    /*** 调用系统相册和裁剪* @param info*/public static void useSystemAlbum(String info){clipX = 0;clipY = 0;try{JSONObject jsonObject = new JSONObject(info);needClip = jsonObject.getInt("needClip");clipX = jsonObject.getInt("clipX");clipY = jsonObject.getInt("clipY");}catch(Exception e){e.printStackTrace();}pickImage();}/*** 选择相册上传图片*/public static void pickImage(){photoType = 1;String[] needPermissions = new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE};List<String> permissionList = new ArrayList<>();for (String permission : needPermissions) {if (ContextCompat.checkSelfPermission(instance, permission) != PackageManager.PERMISSION_GRANTED)permissionList.add(permission);}if (permissionList.size() == 0) {
//            Log.i("pickImg","已经获取到所有权限");goPhotoAlbum();}else{String[] requestPermissions = permissionList.toArray(new String[permissionList.size()]);ActivityCompat.requestPermissions(instance,requestPermissions, 1001);}}public static void goPhotoAlbum(){Intent intentAlbum= new Intent(Intent.ACTION_PICK, null);//其中External为sdcard下的多媒体文件,Internal为system下的多媒体文件。//使用INTERNAL_CONTENT_URI只能显示存储在内部的照片intentAlbum.setDataAndType(MediaStore.Images.Media.INTERNAL_CONTENT_URI, "image/*");//返回结果和标识instance.startActivityForResult(intentAlbum, REQUEST_CODE_ALBUM);}

调用相机,动态获取权限

    /*** 调用系统相机和裁剪* @param info*/public static void useSystemCamera(String info){clipX = 0;clipY = 0;try{JSONObject jsonObject = new JSONObject(info);needClip = jsonObject.getInt("needClip");clipX = jsonObject.getInt("clipX");clipY = jsonObject.getInt("clipY");}catch(Exception e){e.printStackTrace();}takePhoto();}/*** 选择相机上传图片*/public static void takePhoto(){photoType = 2;
//        Log.i("pickImg","takePhoto调用");String[] needPermissions = new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA};List<String> permissionList = new ArrayList<>();for (String permission : needPermissions) {if (ContextCompat.checkSelfPermission(instance, permission) != PackageManager.PERMISSION_GRANTED)permissionList.add(permission);}if (permissionList.size() == 0) {
//            Log.i("pickImg","已经获取到所有权限");callCamera();}else{String[] requestPermissions = permissionList.toArray(new String[permissionList.size()]);ActivityCompat.requestPermissions(instance,requestPermissions, 1002);}}public static void callCamera(){Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 判断是否有相机if (captureIntent.resolveActivity(instance.getPackageManager()) != null) {File photoFile = null;Uri photoUri = null;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {// 适配android 10photoUri = createImageUri();} else {try {photoFile = createImageFile();} catch (IOException e) {e.printStackTrace();}if (photoFile != null) {mCameraImagePath = photoFile.getAbsolutePath();
//                    System.out.println("path = "+mCameraImagePath);if (/*Build.VERSION.SDK_INT >= Build.VERSION_CODES.N*/true) {//7.0到9.0//适配Android 7.0文件权限,通过FileProvider创建一个content类型的Uri 如:content://photoUri = FileProvider.getUriForFile(instance,"com.heart.LudoMatePro.fileprovider", photoFile);} else {//7.0以下, 如:file://photoUri = Uri.fromFile(photoFile);}}}System.out.println("photoUri = "+photoUri);mCameraUri = photoUri;if (photoUri != null) {if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {List<ResolveInfo> resInfoList = instance.getPackageManager().queryIntentActivities(captureIntent, PackageManager.MATCH_DEFAULT_ONLY);for (ResolveInfo resolveInfo : resInfoList) {String packageName = resolveInfo.activityInfo.packageName;instance.grantUriPermission(packageName, photoUri,Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);}}captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);captureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);instance.startActivityForResult(captureIntent, REQUEST_CODE_CAMERA);}}}/*** 创建图片地址uri,用于保存拍照后的照片 Android 10以后使用这种方法* @return 图片的uri*/private static Uri createImageUri() {//设置保存参数到ContentValues中ContentValues contentValues = new ContentValues();//设置文件名contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, System.currentTimeMillis()+"");//兼容Android Q和以下版本if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {//android Q中不再使用DATA字段,而用RELATIVE_PATH代替//TODO RELATIVE_PATH是相对路径不是绝对路径;照片存储的地方为:内部存储/Pictures/preventprocontentValues.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/preventpro");}//设置文件类型contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/JPEG");//执行insert操作,向系统文件夹中添加文件//EXTERNAL_CONTENT_URI代表外部存储器,该值不变Uri uri = instance.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);return uri;}/*** 创建保存图片的文件* @return* @throws IOException*/private static File createImageFile() throws IOException {String imageName = new SimpleDateFormat("yyyyMMdd_HHmmss",Locale.getDefault()).format(new Date()) +".jpg";
//        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
//        File storageDir = Environment.getExternalStoragePublicDirectory(
//                Environment.DIRECTORY_PICTURES);File storageDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"Pictures"+File.separator+"abc");if (!storageDir.exists()) storageDir.mkdirs();File tempFile = new File(storageDir, imageName);if (!Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(tempFile))) {return null;}return tempFile;}

3.处理相机相册选取回调

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);FaceBookLogin.callbackManager.onActivityResult(requestCode, resultCode, data);SDKWrapper.getInstance().onActivityResult(requestCode, resultCode, data);if(requestCode == REQUEST_CODE_ALBUM && resultCode == RESULT_OK){Log.i("pickImg ","调用相册回调");if(data != null){if(needClip == 1){startPhotoZoom(data.getData());return;}String filePath = null;if (resultCode == RESULT_OK) {//判断手机的系统版本号if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//4.4系统的及以上用此方法处理照片filePath =  handleImageOnKitkat(data);} else {// 4.4以下的使用这个方法处理照片filePath =  handleImageBeforeKitkat(data);}}File file = new File(filePath);Bitmap bitmap = BitmapFactory.decodeFile(filePath);String base64Bitmap = bitmapToBase64(bitmap);final String callJsFunc = String.format("PlatForm.onPickImageResult(\'%s\',\'%s\');",filePath,base64Bitmap);instance.runOnGLThread(new Runnable() {@Overridepublic void run() {Cocos2dxJavascriptJavaBridge.evalString(callJsFunc);Log.i("pickImg","返回path,base64,callFuncStr = "+callJsFunc);}});}}else if(requestCode == REQUEST_CODE_CAMERA && resultCode == RESULT_OK){Bitmap bitmap = null;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {if(needClip == 1){startPhotoZoom(mCameraUri);return;}String filePath = changeUriToPath(mCameraUri);bitmap = BitmapFactory.decodeFile(filePath);String base64Bitmap = bitmapToBase64(bitmap);final String callJsFunc = String.format("PlatForm.onPickImageResult(\'%s\',\'%s\');",filePath,base64Bitmap);instance.runOnGLThread(new Runnable() {@Overridepublic void run() {Cocos2dxJavascriptJavaBridge.evalString(callJsFunc);Log.i("pickImg","返回path,base64,callFuncStr = "+callJsFunc);}});} else {bitmap = BitmapFactory.decodeFile(mCameraImagePath);String base64Bitmap = bitmapToBase64(bitmap);Log.i("pickImg ","base64Image222 = "+base64Bitmap);final String callJsFunc = String.format("PlatForm.onPickImageResult(\'%s\',\'%s\');",mCameraImagePath,base64Bitmap);instance.runOnGLThread(new Runnable() {@Overridepublic void run() {Cocos2dxJavascriptJavaBridge.evalString(callJsFunc);Log.i("pickImg","返回path,base64,callFuncStr = "+callJsFunc);}});}}else if(requestCode == REQUEST_CODE_CROP && resultCode == RESULT_OK){Log.i("pickImg","裁剪完成"+data.getData());if(data != null){if(photoType == 1){String filePath = null;if (resultCode == RESULT_OK) {//判断手机的系统版本号if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//4.4系统的及以上用此方法处理照片
//                            filePath =  handleImageOnKitkat(data);filePath  = changeUriToPath(uriClipUri);} else {// 4.4以下的使用这个方法处理照片
//                            filePath =  handleImageBeforeKitkat(data);filePath = getImagePath(uriClipUri, null);}}File file = new File(filePath);Bitmap bitmap = BitmapFactory.decodeFile(filePath);String base64Bitmap = bitmapToBase64(bitmap);final String callJsFunc = String.format("PlatForm.onPickImageResult(\'%s\',\'%s\');",filePath,base64Bitmap);instance.runOnGLThread(new Runnable() {@Overridepublic void run() {Cocos2dxJavascriptJavaBridge.evalString(callJsFunc);Log.i("pickImg","crop返回path,base64,callFuncStr = "+callJsFunc);}});}else if(photoType == 2){Bitmap bitmap = null;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {String filePath = changeUriToPath(mCameraUri);bitmap = BitmapFactory.decodeFile(filePath);String base64Bitmap = bitmapToBase64(bitmap);final String callJsFunc = String.format("PlatForm.onPickImageResult(\'%s\',\'%s\');",filePath,base64Bitmap);instance.runOnGLThread(new Runnable() {@Overridepublic void run() {Cocos2dxJavascriptJavaBridge.evalString(callJsFunc);Log.i("pickImg","返回path,base64,callFuncStr = "+callJsFunc);}});} else {bitmap = BitmapFactory.decodeFile(mCameraImagePath);String base64Bitmap = bitmapToBase64(bitmap);final String callJsFunc = String.format("PlatForm.onPickImageResult(\'%s\',\'%s\');",mCameraImagePath,base64Bitmap);instance.runOnGLThread(new Runnable() {@Overridepublic void run() {Cocos2dxJavascriptJavaBridge.evalString(callJsFunc);Log.i("pickImg","返回path,base64,callFuncStr = "+callJsFunc);}});}}}}}

处理图片路径4.4之后

private String handleImageOnKitkat(Intent data) {String imagePath = null;Uri uri = data.getData();imagePath = changeUriToPath(uri);return imagePath;}private String changeUriToPath(Uri uri){String imagePath = null;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {if (DocumentsContract.isDocumentUri(this, uri)) {//如果是document类型的uri,则通过document id 处理String docId = DocumentsContract.getDocumentId(uri);if("com.android.providers.media.documents".equals(uri.getAuthority())) {//解析出数字格式的idString id  = docId.split(":")[1];String selection = MediaStore.Images.Media._ID+ "=" +id;imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection );} else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(docId));imagePath = getImagePath(contentUri, null);}} else if ("content".equalsIgnoreCase(uri.getScheme())) {//如果是content类型的uri,则用普通方式处理imagePath = getImagePath(uri, null);} else if ("file".equalsIgnoreCase(uri.getScheme())) {//如果是file类型的uri,直接获取图片路径imagePath = uri.getPath();}}return imagePath;}

处理图片路径4.4之前

private String handleImageBeforeKitkat(Intent data) {Uri uri = data.getData();String imagePath = getImagePath(uri, null);return imagePath;}private String getImagePath(Uri uri,String selection) {String path = null;//通过uri 和 selection 获取真实的图片路径Cursor cursor = getContentResolver().query(uri,null,selection,null,null);if (cursor != null) {if (cursor.moveToFirst()) {path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));}cursor.close();}return path;}

裁剪的方法

/*** 图片裁剪的方法* @param uri*/public void startPhotoZoom(Uri uri) {
//        Log.i("pickImg uri=====", "" + uri);//com.android.camera.action.CROP,这个action是调用系统自带的图片裁切功能Intent intent = new Intent("com.android.camera.action.CROP");intent.setDataAndType(uri, "image/*");//裁剪的图片uri和图片类型intent.putExtra("crop", true);//设置允许裁剪,如果不设置,就会跳过裁剪的过程,还可以设置putExtra("crop", "circle")intent.putExtra("aspectX", 1);//裁剪框的 X 方向的比例,需要为整数intent.putExtra("aspectY", 1);//裁剪框的 Y 方向的比例,需要为整数
//        intent.putExtra("outputX", 60);//返回数据的时候的X像素大小。
//        intent.putExtra("outputY", 60);//返回数据的时候的Y像素大小。if(clipX != 0 && clipY != 0){intent.putExtra("OutputX", clipX);// 设置最终裁剪的宽和高intent.putExtra("OutputY", clipY);// 设置最终裁剪的宽和高
//            Log.i("pickImg","设置裁剪输出宽和高="+clipX+"-"+clipY);}//uriClipUri为Uri类变量,实例化uriClipUriif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {if (photoType == 2) {//如果是7.0的拍照//开启临时访问的读和写权限intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);//针对7.0以上的操作intent.setClipData(ClipData.newRawUri(MediaStore.EXTRA_OUTPUT, uri));uriClipUri = uri;} else if(photoType == 1) {//如果是7.0的相册//设置裁剪的图片地址UriuriClipUri = Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath() + "/" +"clip.jpg");
//                Log.i("pickImg","android 7.0调用相册= "+uriClipUri);}} else {uriClipUri = Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath() + "/" + "clip.jpg");}
//        Log.i("pickImg uriClipUri=====", "" + uriClipUri);//Android 对Intent中所包含数据的大小是有限制的,一般不能超过 1M,否则会使用缩略图 ,所以我们要指定输出裁剪的图片路径intent.putExtra(MediaStore.EXTRA_OUTPUT, uriClipUri);intent.putExtra("return-data", false);//是否将数据保留在Bitmap中返回intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());//输出格式,一般设为Bitmap格式及图片类型intent.putExtra("noFaceDetection", true);//人脸识别功能startActivityForResult(intent, REQUEST_CODE_CROP);//裁剪完成的标识}

Bitmap转base64字符串,30位压缩质量为原来的30%

public static String bitmapToBase64(Bitmap bitmap) {String result = null;ByteArrayOutputStream baos = null;try {if (bitmap != null) {baos = new ByteArrayOutputStream();bitmap.compress(Bitmap.CompressFormat.JPEG, 30, baos);baos.flush();baos.close();byte[] bitmapBytes = baos.toByteArray();result = Base64.encodeToString(bitmapBytes, Base64.NO_WRAP);}} catch (IOException e) {e.printStackTrace();Log.i("pickImg","io exception111");} finally {try {if (baos != null) {baos.flush();baos.close();}} catch (IOException e) {Log.i("pickImg","io exception222");e.printStackTrace();}}return result;}

AndroidManifest.xml里面增加FileProvider配置

 <providerandroid:name="androidx.core.content.FileProvider"android:authorities="你的包名.fileprovider"android:grantUriPermissions="true"android:exported="false"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" /></provider>

另外,上面定义了xml/file_paths,需要在res目录下面创建xml文件加和file_paths.xml文件

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 The Android Open Source ProjectLicensed under the Apache License, Version 2.0 (the "License");you may not use this file except in compliance with the License.You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions andlimitations under the License.
--><paths xmlns:android="http://schemas.android.com/apk/res/android"><!-- Offer access to files under Context.getCacheDir() --><cache-path name="my_cache" /><files-path name="my_files" path = "." /><external-path name="my_external" path = "." /><external-path path="xxxx" name="camera_photos" />
</paths>

cocos creator 调用相机相册裁剪图片并上传到服务器相关推荐

  1. html5在线裁剪,HTML5 本地裁剪图片并上传至服务器(老梗)

    很多情况下用户上传的图片都需要经过裁剪,比如头像啊什么的.但以前实现这类需求都很复杂,往往需要先把图片上传到服务器,然后返回给用户,让用户确定裁剪坐标,发送给服务器,服务器裁剪完再返回给用户,来回需要 ...

  2. html5图片区域剪切,HTML5 本地裁剪图片并上传至服务器(老梗)

    很多情况下用户上传的图片都需要经过裁剪,比如头像啊什么的.但以前实现这类需求都很复杂,往往需要先把图片上传到服务器,然后返回给用户,让用户确定裁剪坐标,发送给服务器,服务器裁剪完再返回给用户,来回需要 ...

  3. react-cropper + antdesign +dva 实现裁剪图片并上传的功能

    react-cropper + antdesign +dva 实现裁剪图片并上传的功能 一.首先安装react-cropper插件 npm install --save react-cropper 执 ...

  4. jquery实现截取pc图片_Cropper.js 实现裁剪图片并上传(PC端)

    由于之前做项目的时候有需求是需要实现裁剪图片来做头像并上传到服务器,所以上网查询了很多资料,也试用了许多案例,发现cropper插件裁剪是比较完善的,所以结合之前的使用情况,编写了此案例.本案例是参考 ...

  5. cropper.js 裁剪图片并上传(文档翻译+demo)(转)

    官网http://fengyuanchen.github.io/cropper/ 文档https://github.com/fengyuanchen/cropper/blob/master/READM ...

  6. 【VUE】Toast-UI/Editor工具实现图片自定义上传到服务器

    Toast-UI/Editor工具实现图片自定义上传到服务器 author: jwensh date: 2021.06.17 文章目录 Toast-UI/Editor工具实现图片自定义上传到服务器 所 ...

  7. MUI调用照片以及裁剪和图库照片上传到服务器【MUI前端部分】

    文章目录 一.效果图展示 二. 前端样式以及JS控制转码 2.1 H5+中的调用相机模块和图库 2.2 拍照上传和从相册里上传的js控制如下 2.3 使用cropper框架实现前端裁剪 2.4 前端文 ...

  8. cropper.js 实现裁剪图片并上传(PC端)

    博客地址:http://blog.mambaxin.com 由于之前做项目的时候有需求是需要实现裁剪图片来做头像并上传到服务器,所以上网查询了很多资料,也试用了许多案例,发现cropper插件裁剪是比 ...

  9. 实现HTML5 裁剪图片并上传

    个人制作图片裁剪的问题总结 在一个上传图片进行打印的项目当中,由于用户上传的图片形状比例千奇百怪,所以需要前端做一个图片裁剪功能.刚开始觉得挺简单的就是做图片裁剪功能,网上的插件一大堆,随便找一个套上 ...

最新文章

  1. 转载的Web.config详解
  2. Hibernate 双向一对一实现(基于annotation)
  3. Flask 快速上手
  4. 基于.NetCore3.1系列 —— 日志记录之日志配置揭秘
  5. 九、一篇文章帮助你读懂CSS属性:vertical-align 垂直对齐
  6. 让全球数亿人拍摄到更美的照片,【北京三星研究院】招聘
  7. matplotlib调整子图尺寸,消除大图白边框
  8. 距离公式汇总以及Python实现
  9. 软件的工程化管理(二)(转)
  10. GIS投影、坐标系、坐标系转换
  11. js动态添加元素时绑定onclick函数
  12. vscode误更新后,无法连接服务器,报“Acquiring lock on/home/~”和“过程试图写入的管道不存在”错误
  13. lambda函数用法及注意事项(简单总结,有待补充)
  14. 用了pcl的地方, 程序直接崩溃 挂掉
  15. Oracle数据更新
  16. [云原生]微服务架构是什么
  17. 第38件事 心理设计的6种方法
  18. 怎么通过微信开发者工具打开一个项目
  19. printf用法补录
  20. android串口获取电子秤数据,c# 打开电子秤串口并读取电子秤数据

热门文章

  1. 《部门负责人的简称》
  2. 关于EBS七层组织架构的一些理解
  3. (ZT)淘宝防骗指南
  4. 动画制作工具Ulead GIF Animator
  5. zabbix源码之zabbix alerter.c报警逻辑
  6. 华南理工大计算机博士毕业条件,华南理工大学博士研究生申请学位发表论文的规定...
  7. adb无法连接夜神模拟器处理以及文件传输
  8. 调制解调器故障诊断与排除(1.0)
  9. python爬虫之Scrapy框架原理及操作实例详解、股票数据Scrapy爬虫
  10. 安装下载Anaconda注意事项,一定注意,否则白费力气