android 拍照图片压缩第三方

最近在开发中遇到了一个比较棘手的问题,由于在之前使用的版本-小于24也就是小于7.0所以在使用相机拍照的时候不会出现问题,但是当版本大于或者等于7.0的时候用原来的方法调用相机就会抛出一个安全异常
通过搜索发现是出于对系统安全的考虑,在sdk24及以上,对相机的操作需要使用才行 。
虽然有些麻烦,但除非用第三方框架,不然也只能自己动手去解决了 。
二、操作流程
1、定义全局标识
用于接收图库选择或拍照完成后的结果回调
//图库
final int= 0; //拍照
final int= 1; //裁剪
final int= 2;
定义全局的uri
Uri ;
2、图库操作
这里用的是一个自定义的
.(new View.() {
@
void (View v) { //调用系统图库,选择图片
= new (., null);
.(
..Media., "image/*"); //返回结果和标识
lt(, );
.();
});
3、相机操作
3.1 .0以下版本
直接调用系统相机 , 通过日志可以看到会返回一个类似
file://///0/temp.jpg的文件
.(new View.() {
@
void (View v) { // 启动系统相机
= new (.); //
获取拍完后的uri
Uri= Uri.(new
File(.(), "temp.jpg"));
【android 拍照图片压缩第三方】.(., ); // 返回结果和标识
lt(, );
.();
});
3.2 兼容.0以上版本
在新的版本中 , 对内容提供者做了限制,返回的不再是uri,而需要一个
使用 ://代替了 file:///
所以如果直接使用原来的方法就会报错 。
所以在之前我们要给文件中标签添加权限
:name="..v4.."
:="你的包名."

android 拍照图片压缩第三方

文章插图
:="false"
:="true">
:name=".."
:="@xml/" />
并且需要创建一个xml
(可以在上面:="@xml/"直接使用快捷键alt+enter创建,然后将代码拷贝进去)
-path标签用来指定Uri共享,name属性的值可以自定义,path属性的值表示共享的具体位置
xmlns:="">
然后在调用系统相机的时候判断
.(new View.() {
@
void (View v) { // 启动系统相机
= new (.);
Uri ; // 判断7.系统
if (Build.. >= Build..N) { //临时添加一个拍照权限
.(.);
//通过获取uri
= .(.this,
"你的包名.", new File(.(),
"temp.jpg"));
.(., );
} else {
= Uri.(new
File(.(), "temp.jpg"));
.(., );
lt(, );
.();
});
4、
使用接收操作完成的回调
@
void (int , int ,
data) { super.(, , data); if ( ==
.) {() { case : //获取拍照结果,执行裁剪
Uri ; //如果是7.系统,直接获取uri
if (Build.. >= Build..N) {
= ;
} else {
= Uri.(new File(
.() + "/temp.jpg"));
(); break; case : //获取图库结果 , 执行裁剪
(data.()); break;
case : //裁剪完成后的操作,上传至服务器或者本地设置
break;
5、裁剪
当拍照完成后或者本地选择图片完毕之后会执行该方法 。同时也做了7.0适配
android 拍照图片压缩第三方

文章插图
/**
* 裁剪图片的方法.
* 用于拍照完成或者选择本地图片之后
*/
Uri ;void (Uri uri) {
Log.e("uri=====", "" + uri);
= new ("com....CROP");
.(uri, "image/*");
.("crop", "true");
.("", 1);
.("", 1);
.("", 60);
.("", 60); //为Uri类变量,实例化
if (Build.. >= Build..N) { //开启临时权限
.(. |
.); //重点:针对7.0以上的操作
.(.(., uri));
= uri;
} else {
= Uri.parse("file://" + "/" +
.().() + "/" + "small.jpg");
.(., );
.("-data", false);
.("", ..JPEG.());
.("", true);
lt(, );
三、裁剪后的处理
在方法还有一个最后的处理,前面只是在给图片做操作 , 下面是将完成后的图片选择加载到本地或者上传到项目的服务端,一般在实际开发中用的比较多
1、加载至本地
使用加载,因为支持Uri、File、类型,不需要做进一步的转换就可以直接用 。
.with(this)
.load()
.into();
2、转成File并压缩、上传
在实际开发中有时候需要对图片进行进一步的处理 , 比如传到服务器需要File类型的文件,所以就需要进行再一次的转换 。
具体可以根据需求来进行相应的操作
//裁剪后的图像转成 =
.(().());//创建路径
path = .()
.() + "/Pic";//获取外部储存目录file = new File(path);Log.e("file",
file.()); //创建新目录file.(); //以当前时间重新命名文件long i =
.(); //生成新的文件file = new File(file.() + "/" + i +
".png");
Log.e("", file.()); //创建输出流
out = new (file.()); //压缩文件 , 返回结果
flag = press(..JPEG, 100, out);
项目demo地址: