欢迎光临散文网 会员登陆 & 注册

Android studio 简单的拍照功能,等比例高清晰度压缩图片

2023-07-12 22:32 作者:翼618  | 我要投稿


这个用第三方不太稳定 我推荐用系统相机就好

压缩用导入得第三方包 叫鲁班什么得,整体效果非常好,

不仅压缩率高,而且不会失真,比例也不用自己算了,用法有很多,可以自己琢磨一下

拍照得出来得图片目标在 

内存根目录 名字叫tempCamera.jpg 

我这里压缩直接替换了,你有需要得话可以保留原图。压缩图片路径在Luban()里面有备注


导包   压缩用到得   拍照用得系统相机 这个兼容性比较好

implementation 'top.zibin:Luban:1.1.8'

// 我这里动态判断权限用到的,你可以用其他的写法 

implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar'
implementation 'io.reactivex.rxjava2:rxjava:2.0.7'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'



--------我是分界线-------------------------------------

权限部分 放在清单里面

    <uses-feature

        android:name="android.hardware.camera"

        android:required="false" />

    <!--CAMER相机权限

        下面是写出权限-->

    <uses-permission android:name="android.permission.CAMERA" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>


还有这个,兼容用的,没有这个拍照好像会报错

<!-- 7.0打开文件专用兼容权限  给一个私有文件权限 -->

<provider

    android:name="android.support.v4.content.FileProvider"

    android:authorities="com.jph.takephoto.fileprovider"

    android:exported="false"

    android:grantUriPermissions="true">

    <meta-data

        android:name="android.support.FILE_PROVIDER_PATHS"

        android:resource="@xml/file_paths" />

</provider>


--------我是分界线-------------------------------------

file_paths.xml 内容  记得新建一个xml文件夹 


<?xml version="1.0" encoding="utf-8"?>

<resources>

    <paths>

        <external-path path="" name="camera_photos" />

    </paths>

</resources>


--------我是分界线-------------------------------------

Activity 部分


 /**

     * 初始保存的图片 兼容性貌似更好     暂时不用 等待测试后结果 再决定是否使用这个  

     */

    public String CAMERA_TEMP = Environment.getExternalStorageDirectory().getPath() + File.separator + "tempCamera.jpg";



    //拍照功能参数

    private static final int TAKE_PHOTO = 1;

    private static final int CHOOSE_PHOTO = 2;

    private final static int CROP_IMAGE = 3;

    private Uri imageUri;





// 动态获取权限后调用拍照

    private void openCamera() {

        RxPermissions rxPermissions = new RxPermissions(A_NdividualCenterActivity.this);

        rxPermissions.request(

                Manifest.permission.WRITE_EXTERNAL_STORAGE,

                Manifest.permission.READ_EXTERNAL_STORAGE,

                Manifest.permission.CAMERA, Manifest.permission.INTERNET)

                .observeOn(AndroidSchedulers.mainThread())

                .subscribe(new Consumer<Boolean>() {

                    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)

                    @Override

                    public void accept(Boolean aBoolean) throws Exception {

                        if (aBoolean) {

                            //申请的权限全部允许

                            openCa();


                        } else {

                            //只要有一个权限被拒绝,就会执行

                            Toast.makeText(A_NdividualCenterActivity.this, "未授权权限,部分功能不能使用", Toast.LENGTH_SHORT).show();

                        }

                    }

                });



    }






   /**

     * 打开相机

     */

    private void openCa() {

        // 创建File对象,用于存储拍照后的图片

        // 将图片命名为output_image.jpg,并将它存放在手机SD卡的应用关联缓存目录下

        // getExternalCacheDir()可以得到这个目录

        // File outputImage = new File(getExternalCacheDir(), "output_image.jpg");

          File outputImage = new File(CAMERA_TEMP);

        try {

            if (outputImage.exists()) {

                outputImage.delete();

            }

            outputImage.createNewFile();

        } catch (IOException e) {

            e.printStackTrace();

        }


        // 进行一个判断

        // 如果运行设备的系统版本低于Android 7.0,就调用Uri的fromFile()方法将File对象转换成Uri对象

        // 这个Uri对象标识着output_image.jpg这张图片的本地真实路径

        // 否则,就调用FileProvider的getUriForFile()方法将File对象转换成一个封装过的Uri对象

        // getUriForFile()方法接收 3个参数,第一个参数要求传入Context对象,第二个参数可以是任意唯一的字符串,第三个参数则是我们刚刚创建的File对象

        // 之所以要进行这样一层转换,是因为从Android 7.0系统开始,直接使用本地真实路径的Uri被认为是不安全的,会抛出一个FileUriExposedException 异常

        // 而FileProvider则是-种特殊的内容提供器,它使用了和内容提供器类似的机制来对数据进行保护,可以选择性地将封装过的Uri共享给外部,从而提高了应用的安全性

        if (Build.VERSION.SDK_INT >= 24) {

            CAMERA_TEMP = Environment.getExternalStorageDirectory().getPath() + File.separator + "tempCamera.jpg";//根目录下 上面也有声明 这里特别写一下 防止找不到

            imageUri = FileProvider.getUriForFile(this, "com.jph.takephoto.fileprovider", new File(CAMERA_TEMP));//通过FileProvider创建一个content类型的Uri

        } else {

            imageUri = Uri.fromFile(outputImage);

        }


        //启用相机程序

        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");

        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

        startActivityForResult(intent, TAKE_PHOTO);

    }



        //打开相册 这里没用到,不过很多人需要 这里写一下 没用到可以忽略

    private void openAlbum() {

        Intent intent_album = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

        startActivityForResult(intent_album, CHOOSE_PHOTO);

    }




  /**

     * 压缩

     */

    private void Luban() {

        Luban.with(this)  //context

                .load(CAMERA_TEMP)  // 需要压缩的图片file

                .ignoreBy(100)   //压缩率 ,默认100,你觉得图片大 这个也可以改一下 图片会小一点

                .setTargetDir(Environment.getExternalStorageDirectory().getPath() + File.separator)  //压缩后文件目录

                .filter(new CompressionPredicate() {

                    @Override

                    public boolean apply(String path) {

                        return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));

                    }

                })

                .setCompressListener(new OnCompressListener() {

                    @Override

                    public void onStart() {

                        // TODO 压缩开始前调用,可以在方法内启动 loading UI

                    }


                    @Override

                    public void onSuccess(File file) {

                        // TODO 压缩成功后调用,返回压缩后的图片文件

                        //如果希望替换原图可以执行这行

                        file.renameTo(new File(CAMERA_TEMP));

                        //将拍摄的照片显示出来

                    }


                    @Override

                    public void onError(Throwable e) {

                        // TODO 当压缩过程出现问题时调用

                    }

                }).launch();

    }









    /**

     * 拍完照后一般会跑这里 你可以在这里处理原图 我这里执行了压缩 并替换原图 

这个放在外面别搞错了

     * 接收图片处理

     * 

     * @param requestCode [description]

     * @param resultCode  [description]

     * @param data        [description]

     */

    @Override

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        super.onActivityResult(requestCode, resultCode, data);

        switch (requestCode) {

            case TAKE_PHOTO:

                if (resultCode == RESULT_OK) {

                    Luban();//执行压缩


                    try {

                        Bitmap bitmap = null;

                        bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));

                        // iv_Camera.setImageBitmap(bitmap);//用一个ImageView展示图片

                    } catch (FileNotFoundException e) {

                        e.printStackTrace();

                    }

                }

                break;

            default:

                break;

        }

    }


--------我是分界线-------------------------------------

附上一张压缩后的图片,原图是5MB,压缩后100KB不到



Android studio 简单的拍照功能,等比例高清晰度压缩图片的评论 (共 条)

分享到微博请遵守国家法律