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;
}