
前言:发现Android 调用系统裁剪时,在各Android 版本出现各种问题,踩了一堆坑,做一下总结,免得以后忘记
后面会有完整裁剪代码
1,一加手机报错intent.putExtra("outputFormat", "png");
这句不能加,否则报错
2,Android 12不能进入裁剪页面不能加
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
否则无法进入裁剪页面
3.Android 12裁剪后无法拿到图片显示
Android11,12申请权限
申请这两个权限,在手机上只会申请媒体文件的访问权限,无法访问全部文件权限,这很重要
全部权限需要用户手动给予
如果用户愿意手动给你这个权限,那么裁剪就不会出现问题,否则就会出现裁剪成功,保存不成功的现象
出现这个原因:我们拥有媒体权限,所以可以打开相册选择图片,进行裁剪,裁剪后的图片会在文件夹,他不属于媒体文件,我们没有这个权限,除非有全部文件权限
解决方案:我们将裁剪后的图片加入到相册,这样裁剪后图片就是媒体文件了,代码后续会放上
4.谷歌手机路劲和普通手机不一致这个要注意一下,谷歌手机最好不要用bundle的形式去拿裁剪后的图片
下面是源码部分1.打开相册
Intent intent = new Intent(Intent.ACTION_PICK);//选择数据的意图 intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_UNSPECIFIED);//设置数据和类型,从图库中获取图片 startActivityForResult(intent, PHOTOZOOM);//执行意图并传入请求码(请求码根据业务需要自行指定)
2.拿到相册uri后进行裁剪
data.getData()是uri
裁剪和得到裁剪拿到图片可以用两种写法
1,用bundle的方式,
优点就是不要读写权限了
缺点就是对裁剪尺寸有限制(500*500),因为intent传值,大小1M,多了报错
2.就用uri了
优点大小无限制
缺点就是要权限
1,uri方式
private void clipPhoto(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
// 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 800);
intent.putExtra("outputY", 800);
intent.putExtra("return-data", false);
intent.putExtra("scale", true);
intent.putExtra("scaleUpIfNeeded", true);
File CROP_TEMP_FILE = Environment.getExternalStorageDirectory();
File mFullPath = new File(CROP_TEMP_FILE, "unheadimage" + System.currentTimeMillis() + ".png");
fileUri = Uri.fromFile(mFullPath);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, PHOTORESULT);
}
2.bundle方式
private void clipPhoto(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
// 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// outputX outputY 是裁剪图片宽高
intent.putExtra("outputX", 100);
intent.putExtra("outputY", 100);
intent.putExtra("circleCrop", true);
intent.putExtra("return-data", true);
startActivityForResult(intent, PHOTORESULT);
}
3.对裁剪的图片处理
同样分2种
1.uri方式
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, fileUri));
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
try {
iView.setImageBitmap(MediaStore.Images.Media.getBitmap(getContentResolver(),fileUri));
} catch (IOException e) {
e.printStackTrace();
}
}
},500);
其中发送广播是为了将图片变成媒体文件,否则他是文件,需要文件权限
2.bundle方式
Bundle bundle = data.getExtras();//把数据取出来,Bundle是一个装数据的可以在activity之间传输的类
Bitmap bitmap = bundle.getParcelable("data");//获取位图
iView.setImageBitmap(bitmap);//设置位图,显示
下面提供一种uri转bitmap的
1,
MediaStore.Images.Media.getBitmap(getContentResolver(),fileUri)
2.
private Bitmap getBitmapFromUri(Context context, Uri uri) {
ParcelFileDescriptor parcelFileDescriptor;
Bitmap mBitmap = null;
try {
parcelFileDescriptor = context.getContentResolver()
.openFileDescriptor(uri, "r");
FileDescriptor fileDescriptor = parcelFileDescriptor
.getFileDescriptor();
mBitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return mBitmap;
}
在提供一种保存bitmap进相册的
public static void saveImageToGallery(Context context, Bitmap bmp) {
// 首先保存图片
File appDir = new File(Environment.getExternalStorageDirectory(), "Boohee");
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = System.currentTimeMillis() + ".jpg";
File file = new File(appDir, fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 其次把文件插入到系统图库
// try {
// MediaStore.Images.Media.insertImage(context.getContentResolver(),
// file.getAbsolutePath(), fileName, null);
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// }
// 最后通知图库更新
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + file.getPath())));
}
完结散花,后续遇到问题,继续完善
-----------------------------------------------------------------------------
补充点:
3.Android 12裁剪后无法拿到图片显示
这个问题新的修改方案
因为intent的建立的文件夹有问题,上面是用的私有域地址,可以用公有域的
可以用getExternalStoragePublicDirectory
获取公域地址方法:
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath()
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)