如何解决Android照相和相册获取图片时剪裁报错的问题?

在Android应用开发中,照相、相册获取图片并剪裁上传头像是一个常见的需求,这一过程可能会遇到各种报错和问题,本文将详细介绍如何通过代码实现这一功能,并提供常见问题的解决方案。

如何解决Android照相和相册获取图片时剪裁报错的问题?

一、调用相机拍照

1、创建文件对象:用于存储相机拍下的照片,并将其保存在SD卡的应用关联缓存目录下。

2、启动相机程序:通过Intent启动相机程序,并将File对象转换为Uri对象传递给相机。

3、处理返回结果:在onActivityResult方法中处理相机返回的结果,如果拍照成功则进行下一步的剪裁操作。

二、从相册选择图片

1、启动相册选择器:通过Intent启动相册选择器,允许用户从相册中选择一张图片。

2、处理返回结果:在onActivityResult方法中处理相册选择器返回的结果,如果选择了图片则进行下一步的剪裁操作。

如何解决Android照相和相册获取图片时剪裁报错的问题?

三、图片剪裁

1、启动剪裁程序:通过Intent启动剪裁程序,设置剪裁参数如宽高比例、输出格式等。

2、处理剪裁结果:在onActivityResult方法中处理剪裁程序返回的结果,如果剪裁成功则将图片设置为头像并上传。

四、完整示例代码

以下是一个完整的示例代码,展示了如何实现上述功能:

public class MainActivity extends AppCompatActivity {
    private static final int REQUE_CODE_CAMERA = 1;
    private static final int REQUE_CODE_PHOTO = 2;
    private static final int REQUE_CODE_CROP = 3;
    private Bitmap cropBitmap;
    private Uri uri;
    private ByteArrayOutputStream baos;
    private String headPicString;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public static File getImageFromCamera(Context context, File cameraFile, int REQUE_CODE_CAMERA, Intent intent) {
        intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File fileDir = HelpUtil.getFile(context, "/Tour/user_photos");
        cameraFile = new File(fileDir.getAbsoluteFile() + "/" + System.currentTimeMillis() + ".jpg");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraFile));
        ((Activity) context).startActivityForResult(intent, REQUE_CODE_CAMERA);
        return cameraFile;
    }
    public static void getImageFromPhoto(Context context, int REQUE_CODE_PHOTO) {
        Intent intent = new Intent(Intent.ACTION_PICK, null);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
        ((Activity) context).startActivityForResult(intent, REQUE_CODE_PHOTO);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case REQUE_CODE_CAMERA:
                    uri = Uri.fromFile(cameraFile);
                    PhotoUtil.startPhotoZoom(context, uri, REQUE_CODE_CROP);
                    break;
                case REQUE_CODE_PHOTO:
                    if (null != data) {//为了取消选取不报空指针用的
                        uri = data.getData();
                        PhotoUtil.startPhotoZoom(context, uri, REQUE_CODE_CROP);
                    }
                    break;
                case REQUE_CODE_CROP:
                    if (uri != null) {
                        cropBitmap = HelpUtil.getBitmapFromUri(uri, context);
                        if (cropBitmap != null) {
                            iv_headphoto.setImageBitmap(cropBitmap);
                            baos = new ByteArrayOutputStream();
                            cropBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                            headPicString = new String(Base64.encode(baos.toByteArray(), 0));
                            UploadPic(headPicString);
                        }
                    }
                    break;
                default:
                    break;
            }
        }
    }
    public static void startPhotoZoom(Context context, Uri uri, int REQUE_CODE_CROP) {
        int dp = 500;
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");
        intent.putExtra("scale", true);
        intent.putExtra("scaleUpIfNeeded", true);
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", dp);
        intent.putExtra("outputY", dp);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        intent.putExtra("return-data", false);
        ((Activity) context).startActivityForResult(intent, REQUE_CODE_CROP);
    }
}

五、常见问题及解决方案

问题 解决方案
拍照后的图片无法保存 确保在AndroidManifest.xml中添加了WRITE_EXTERNAL_STORAGE权限,并在运行时请求该权限,检查文件路径是否正确。
从相册选择图片时报NullPointerException 在调用startActivityForResult之前,确保已经正确初始化了Intent,并设置了正确的数据类型。
剪裁后的图片无法显示 确保在剪裁Intent中正确设置了输出格式和宽高比例,并在onActivityResult中正确处理返回的Bitmap。
Android7.0以上版本使用本地Uri导致异常 使用FileProvider封装File对象为Uri,并在manifest文件中注册相应的provider。

六、相关问题与解答

问:如何确保在Android7.0以上版本中使用本地Uri不会导致异常?

答:在Android7.0以上版本中,直接使用本地Uri被认为是不安全的,会抛出FileUriExposedException异常,为了解决这个问题,可以使用FileProvider来封装File对象为Uri,具体步骤如下:

如何解决Android照相和相册获取图片时剪裁报错的问题?

1、在res目录下创建一个xml目录,并在其中创建一个provider_paths.xml文件,用于指定Uri的共享路径。

2、在AndroidManifest.xml中注册FileProvider,并指定authorities属性值与provider_paths.xml中的name属性值一致。

3、使用FileProvider.getUriForFile()方法将File对象封装为Uri,并传递给相机或剪裁程序。

以上内容就是解答有关“android照相、相册获取图片剪裁报错的解决方法”的详细内容了,我相信这篇文章可以为您解决一些疑惑,有任何问题欢迎留言反馈,谢谢阅读。

原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/636635.html

Like (0)
Donate 微信扫一扫 微信扫一扫
K-seo的头像K-seoSEO优化员
Previous 2024-11-09 22:50
Next 2024-11-09 22:56

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

免备案 高防CDN 无视CC/DDOS攻击 限时秒杀,10元即可体验  (专业解决各类攻击)>>点击进入