Android 拍照或者相册选择图片后旋转问题修复

Tip: Glide 加载图片小技巧

  • 使用 Glide 加载图片,如果加载不出来可以给其设置监听,打印错误的信息,可以得到原因。
    如有的页面第一次进来不加载图片,第二次进来才加载出来,这时候可以用以上方法去验证错误信息,我出现的情况是:
    java.lang.IllegalArgumentException: bitmap size exceeds 32bits
    所以根据这个提示去搜索答案会很接近了。

  • 出现这个原因是缩放比例不对导致内存溢出,可以先检查代码是否有缩放图片,
    有的话,修改正确的缩放比例即可;
    没有的话有可能是图片的宽高设置太大了,如:
    都设置为 match_parent
    解决办法就是设置固定的值

Tip: 记得申请权限哦!!

获取图片:拍照或者是相册

拍照:
private void pickCameraImage() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
    String fileName;
    //通过时间戳区别文件名
    String timeStamp = String.valueOf(new Date().getTime());
    fileName = "IMG_" + timeStamp + "_";
    try {
        AlbumUtil.deleteAllFiles(getActivity().getExternalCacheDir());
        File photoFile = File.createTempFile(fileName, ".jpg", getActivity().getExternalCacheDir());
        //Environment.getExternalStorageDirectory());//mContext.getCacheDir());
        if (photoFile != null) {
            cameraUri = Uri.fromFile(photoFile);
            //将Uri传递给系统相机
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri);
            getActivity().startActivityForResult(takePictureIntent, PublishActivity.RequestCode.REQUEST_CODE_TAKE_PHOTO);
        }else {
            Toast.makeText(getActivity(), "获取相机图片路径失败", Toast.LENGTH_SHORT).show();
        }
    }catch (IOException e) {
        Log.e(TAG, "获取相机图片失败");
        Toast.makeText(getActivity(), "获取相机图片失败", Toast.LENGTH_SHORT).show();
    }
}else {
    Toast.makeText(getActivity(), "调取相机失败", Toast.LENGTH_SHORT).show();
}
}
相册读取:这里使用了知乎库
private void pickAlbumImage() {
int addCount = 9-this.bitmapArrayList.size()-this.urlArrayList.size();
if (addCount <= 0) {
    Toast.makeText(getActivity(), "最多选择9张图片", Toast.LENGTH_SHORT).show();
    return;
}
Matisse.from(getActivity())
        //图片/视频格式
        .choose(MimeType.allOf())
        //设置主题,默认知乎主题
        .theme(R.style.Matisse_Dracula)
        //设置选取数自动增加
        .countable(true)
        //是否带拍照
//                    .capture(true)
        //设置保存图片权限策略
//                    .captureStrategy(
//                            new CaptureStrategy(true, "com.zhihu.matisse.sample.fileprovider"))
        //图片选取最大数
        .maxSelectable(addCount)
        //选择item增加过滤器,可以将之前选过的选中
//                    .addFilter(new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K))
        //设置媒体网格的期望大小,以适应不同屏幕大小
        .gridExpectedSize(getResources().getDimensionPixelSize(R.dimen.grid_expected_size))
        //设置Activity方向
        .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
        //设置图片缩略图
        .thumbnailScale(0.85f)
        //设置图片引擎,默认Glide
        .imageEngine(new GlideEngine())
        //开始选取照片、等待结果
        .forResult(REQUEST_CODE_PICK_IMAGE);
}

在 onActivityResult 中处理,

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_PICK_IMAGE) {
   Log.e(TAG, "相册结果 onActivityResult: data=="+data);
   // 从相册选择了照片。
   if (data != null) {
       List<Uri> uris = Matisse.obtainResult(data);
       for (Uri uri : uris) {
           Bitmap bitmap = null ;
           try {
               String albumStringPath = AlbumUtil.getRealPathFromURI(getActivity(), uri);
               bitmap = ImageUtil.returnRotatePhoto(albumStringPath, getActivity());

           } catch (Exception e) {
               e.printStackTrace();
           }
           this.bitmapArrayList.add(bitmap) ;
       }
       refreshImages();
   }
}else if (requestCode == PublishActivity.RequestCode.REQUEST_CODE_TAKE_PHOTO){
   Log.e(TAG, "拍照结果 onActivityResult: data=="+data);
   if (cameraUri != null) {
       try {

           // 从uri读取bitmap
           Bitmap bitmap = ImageUtil.returnRotatePhoto(cameraUri.getPath(),getActivity());
           if (bitmap == null) {
               // 取消并返回
           }else {
               this.bitmapArrayList.add(bitmap);
               refreshImages();
           }
       }catch (Exception e) {
           Log.e(TAG, "onActivityResult: 无法读取图片");
       }
   }else {
       Log.e(TAG, "onActivityResult: 无法读取图片 000");
   }
}
}

两个工具类

  • AlbumUtils
public static String getRealPathFromURI(Activity activity, Uri uri) {

       int sdkVersion = Build.VERSION.SDK_INT;
       if (sdkVersion >= 19) { // api >= 19
           return getRealPathFromUriAboveApi19(activity, uri);
       } else { // api < 19
           return getRealPathFromUriBelowAPI19(activity, uri);
       }
   }

   private static String getRealPathFromUriBelowAPI19(Activity activity, Uri uri) {
       String[] proj = {MediaStore.Audio.Media.DATA};
       Cursor cursor = activity.getContentResolver().query(uri, proj, null, null, null);
       cursor.moveToFirst();
       int columnIndex = cursor.getColumnIndex(proj[0]);
       String picturePath = cursor.getString(columnIndex);
       cursor.close();
       return picturePath;
   }

   /**
    * 适配api19及以上,根据uri获取图片的绝对路径
    *
    * @param activity 上下文对象
    * @param uri     图片的Uri
    * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
    */
   @SuppressLint("NewApi")
   private static String getRealPathFromUriAboveApi19(Activity activity, Uri uri) {
       String filePath = null;
       if (DocumentsContract.isDocumentUri(activity, uri)) {
           // 如果是document类型的 uri, 则通过document id来进行处理
           String documentId = DocumentsContract.getDocumentId(uri);
           if (isMediaDocument(uri)) { // MediaProvider
               // 使用':'分割
               String id = documentId.split(":")[1];

               String selection = MediaStore.Images.Media._ID + "=?";
               String[] selectionArgs = {id};
               filePath = getDataColumn(activity, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs);
           } else if (isDownloadsDocument(uri)) { // DownloadsProvider
               Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(documentId));
               filePath = getDataColumn(activity, contentUri, null, null);
           }
       } else if ("content".equalsIgnoreCase(uri.getScheme())){
           // 如果是 content 类型的 Uri
           filePath = getDataColumn(activity, uri, null, null);
       } else if ("file".equals(uri.getScheme())) {
           // 如果是 file 类型的 Uri,直接获取图片对应的路径
           filePath = uri.getPath();
       }
       Log.e(TAG,"real path = "+filePath) ;
       return filePath;
   }

   /**
    * 获取数据库表中的 _data 列,即返回Uri对应的文件路径
    * @return
    */
   private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
       String path = null;

       String[] projection = new String[]{MediaStore.Images.Media.DATA};
       Cursor cursor = null;
       try {
           cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
           if (cursor != null && cursor.moveToFirst()) {
               int columnIndex = cursor.getColumnIndexOrThrow(projection[0]);
               path = cursor.getString(columnIndex);
           }
       } catch (Exception e) {
           if (cursor != null) {
               cursor.close();
           }
       }
       return path;
   }
  • ImageUtil
/**
    * 处理旋转后的图片
    * @param originpath 原图路径
    * @return 返回修复完毕后的 bitmap
    */
   public static Bitmap returnRotatePhoto(String originpath, Context context) {

       // 取得图片旋转角度
       int angle = readPictureDegree(originpath);

       // 把原图压缩后得到Bitmap对象
       Bitmap bmp = getCompressPhoto(originpath, context);

       // 修复图片被旋转的角度
       Bitmap bitmap = rotaingImageView(angle, bmp);

       // 保存修复后的图片并返回保存后的图片路径
       return bitmap;
   }

   /**
    * 读取照片旋转角度
    *
    * @param path 照片路径
    * @return 角度
    */
   public static int readPictureDegree(String path) {
       int degree = 0;
       try {
           ExifInterface exifInterface = new ExifInterface(path);
           int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
           Log.e(TAG, "readPictureDegree: orientation-------->"+orientation);
           switch (orientation) {
               case ExifInterface.ORIENTATION_ROTATE_90:
                   degree = 90;
                   break;
               case ExifInterface.ORIENTATION_ROTATE_180:
                   degree = 180;
                   break;
               case ExifInterface.ORIENTATION_ROTATE_270:
                   degree = 270;
                   break;
           }
       } catch (IOException e) {
           e.printStackTrace();
       }
       Log.e(TAG, "readPictureDegree: degree-origin------->"+degree);
       return degree;
   }

   /**
    * 旋转图片
    * @param angle 被旋转角度
    * @param bitmap 图片对象
    * @return 旋转后的图片
    */
   public static Bitmap rotaingImageView(int angle, Bitmap bitmap) {
       Bitmap returnBm = null;
       // 根据旋转角度,生成旋转矩阵
       Matrix matrix = new Matrix();
       matrix.postRotate(angle);
       try {
           // 将原始图片按照旋转矩阵进行旋转,并得到新的图片
           returnBm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
       } catch (OutOfMemoryError e) {
       }
       if (returnBm == null) {
           returnBm = bitmap;
       }
       if (bitmap != returnBm) {
           bitmap.recycle();
       }
       return returnBm;
   }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_龙衣

赏杯快乐水喝喝

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值