欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-04-09 09:15:12
...

大致思路就是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添加调用相册相机权限

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

  • 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 10
                photoUri = 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/preventpro
            contentValues.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.处理相机相册选取回调


    @Override
    protected 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() {
                    @Override
                    public 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() {
                    @Override
                    public 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() {
                    @Override
                    public 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() {
                        @Override
                        public 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() {
                            @Override
                            public 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() {
                            @Override
                            public 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())) {
                    //解析出数字格式的id
                    String 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类变量,实例化uriClipUri
        if (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的相册
                //设置裁剪的图片地址Uri
                uriClipUri = 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配置

 <provider
      android:name="androidx.core.content.FileProvider"
      android:authorities="你的包名.fileprovider"
      android:grantUriPermissions="true"
      android:exported="false">
      <meta-data
          android: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 Project

     Licensed 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 at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed 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 and
     limitations 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>