两种android图片裁剪方式

一:相机拍完照之后利用系统自带裁剪工具进行截取

    public static void cropImage(Activity activity, Uri srcUri) {
        cropImageUri = srcUri;

        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(srcUri, "image/*");
        intent.putExtra("crop", "true");

        
        // 1.宽高和比例都不设置时,裁剪框可以自行调整(比例和大小都可以随意调整)
        ////////////////////////////////////////////////////////////////
        // 2.只设置裁剪框宽高比(aspect),裁剪框比例固定不可调整,只能调整大小
        ////////////////////////////////////////////////////////////////
        // 3.裁剪后生成图片宽高(output)的设置和裁剪框无关,只决定最终生成图片大小
        ////////////////////////////////////////////////////////////////
        // 4.裁剪框宽高比例(aspect)可以和裁剪后生成图片比例(output)不同,此时,
        //	会以裁剪框的宽为准,按照裁剪宽高比例生成一个图片,该图和框选部分可能不同,
        //  不同的情况可能是截取框选的一部分,也可能超出框选部分,向下延伸补足
        ////////////////////////////////////////////////////////////////

        // aspectX aspectY 是裁剪框宽高的比例
//        intent.putExtra("aspectX", 1);
//        intent.putExtra("aspectY", 1);
//        // outputX outputY 是裁剪后生成图片的宽高
//        intent.putExtra("outputX", 300);
//        intent.putExtra("outputY", 300);

        // return-data为true,会直接返回bitmap数据,但是大图裁剪时会出现问题,推荐下面为false时的方式
        // return-data为false,不会返回bitmap,但需要指定一个MediaStore.EXTRA_OUTPUT保存图片uri
        intent.putExtra(MediaStore.EXTRA_OUTPUT, cropImageUri);
        intent.putExtra("return-data", false);

        activity.startActivityForResult(intent, CROP_IMAGE);
    }
    

这样图片可以通过手势来自由裁剪

二:自定义相机拍照界面,裁剪固定区域的图片

这里用到了一个叫idcardcamera的三方,在此向原作者致敬,附上项目引用地址 ‘com.github.wildma:IDCardCamera:1.0.0’
有几个地方,需要修改一下,我是在相机中间加了一个长方形的框,代码片段如下:

    float screenMinSize = Math.min(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
        //根据screenMinSize,计算出cameraPreview的较宽的一边,长宽比为标准的16:9
        float maxSize = screenMinSize / 9.0f * 16.0f;
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams((int) maxSize, (int) screenMinSize);
        layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
        mCameraPreview.setLayoutParams(layoutParams);
        float height = (int) (screenMinSize * 0.3);
        float density = getResources().getDisplayMetrics().density;  // 屏幕密度(0.75 / 1.0 / 1.5)
        float mywdith =(int) 136*density;
        int widthPixels = getResources().getDisplayMetrics().widthPixels;
        float width = (int) (widthPixels-mywdith);//75 47
        LinearLayout.LayoutParams containerParams = new LinearLayout.LayoutParams((int) width, ViewGroup.LayoutParams.MATCH_PARENT);
        LinearLayout.LayoutParams cropParams = new LinearLayout.LayoutParams((int) width, (int) height);
        mLlCameraCropContainer.setLayoutParams(containerParams);
        mIvCameraCrop.setLayoutParams(cropParams);

修改了 mIvCameraCrop的大小,给这个长方形框添加一个背景边框,刚开始老是显示不出来右边的边框,后来发现,拍照按钮父布局的宽度为136dp,用代码计算出实际占用的px,然后设置长方形的合适宽度,这样就遮挡不住了,右边的边框就能够显示出来了,附上拍照的逻辑,选择自动剪裁

    /**
     * 拍照
     */
    private void takePhoto() {
        mCameraPreview.setEnabled(false);
        mCameraPreview.takePhoto(new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(final byte[] data, Camera camera) {
//                camera.stopPreview();
                camera.startPreview();
                //子线程处理图片,防止ANR

//                setCropLayout();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                        String imagePath = path;
                        ImageUtils.save(bitmap, imagePath, Bitmap.CompressFormat.JPEG);
                        int rotation = getWindowManager().getDefaultDisplay().getRotation();
                        int angle = ImageUtils.getBitmapDegree(imagePath);
                        if (mOrientation==90){
                            bitmap = ImageUtils.rotateBitmap(CameraActivity.this.bitmap, 180);
                        }

                        /*计算裁剪位置*/
                        float left, top, right, bottom;
                        left = ((float) mLlCameraCropContainer.getLeft() - (float) mCameraPreview.getLeft()) / (float) mCameraPreview.getWidth();
                        top = (float) mIvCameraCrop.getTop() / (float) mCameraPreview.getHeight();
                        right = (float) mLlCameraCropContainer.getRight() / (float) mCameraPreview.getWidth();
                        bottom = (float) mIvCameraCrop.getBottom() / (float) mCameraPreview.getHeight();

                        /*自动裁剪*/
                        mCropBitmap = Bitmap.createBitmap(bitmap,
                                (int) (left * (float) bitmap.getWidth()),
                                (int) (top * (float) bitmap.getHeight()),
                                (int) ((right - left) * (float) bitmap.getWidth()),
                                (int) ((bottom - top) * (float) bitmap.getHeight()));

                        /*手动裁剪*/
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                //将裁剪区域设置成与扫描框一样大
                                setCropLayout();
                                mCropImageView.setLayoutParams(new LinearLayout.LayoutParams(mIvCameraCrop.getWidth(), mIvCameraCrop.getHeight()));
                                mCropImageView.setImageBitmap( mCropBitmap);
                            }
                        });
                    }
                }).start();
                safeToTakePicture = true;
            }
        });
    }

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值