camera2自定义相机,拍取矩形框内照片

本文介绍了如何使用camera2 API来解决在特定矩形区域内拍照并进行任意裁剪的问题。在华为荣耀API 21的设备上遇到返回照片尺寸固定的问题,通过camera2成功解决。主要思路是在预览图上绘制矩形框,计算出矩形框内的实际拍摄区域,然后利用Bitmap.createBitmap()创建所需图片。完整代码已上传至GitHub供参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  前段时间,公司项目有个要求,拍照要获取矩形里面的照片,而且还可以任意裁剪后再上传的,做出来后遇到了一个坑,在华为荣耀手机api为21的手机里无论怎么调,它返回的照片就是400*320的,其它手机没问题,折腾好久,用camera2解决了这个问题,…不知道是不是他们工程师把图片分辨率返回那个接口搞死了还是怎样,不多说了先上图片

ps:框是红色的,是录制gif的时候,颜色变了。
  思路:在预览照片的屏幕上面,用draw画出是个矩形角,然后获取在屏幕上的四个矩形角分别距离原图(原则上是屏幕边缘)边缘有多少距离,然后原图的宽和高分别减去他们,剩下的就是矩形里面的宽高(即矩形框里面照片的宽高),拍照保存之前算出这些参数,然后再利用Bitmap.createBitmap()去创建图片

在屏幕上画矩形的代码:

public class DrawRectView extends ImageView{
    private int width;
    private int height;
    private int maskWidth;
    private int maskHeight;
    private Paint linePaint;


    public DrawRectView(Context context, int width) {
        super(context);
        init();
    }

    public DrawRectView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public DrawRectView(Context context, AttributeSet attrs, int defStyleAttr, int width) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {

        linePaint = new Paint();
        linePaint.setAntiAlias(true);
        linePaint.setColor(Color.RED);
        linePaint.setStyle(Style.FILL);
        linePaint.setStrokeWidth(8f);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int h = Math.abs((height-maskHeight)/2);
        int w = Math.abs((width-maskWidth)/2);
//        Log.i("myLog","w "+ w+" h " +h);

        //画矩形框的四个角
        //左上角
        canvas.drawLine(w,h,w+30,h,linePaint);// _
        canvas.drawLine(w,h,w,h+30,linePaint);// |
        //左下角
        canvas.drawLine(w,h+maskHeight,w,h+maskHeight-30,linePaint);// |
        canvas.drawLine(w,h+maskHeight,w+30,h+maskHeight,linePaint);// _
        //右上角
        canvas.drawLine(w+maskWidth,h,w+maskWidth-30,h,linePaint);// _
        canvas.drawLine(w+maskWidth,h,w+maskWidth,h+30,linePaint);// |
        //右下角
        canvas.drawLine(w+maskWidth,h+maskHeight,w+maskWidth,h+maskHeight-30,linePaint);// |
        canvas.drawLine(w+maskWidth,h+maskHeight,w+maskWidth-30,h+maskHeight,linePaint);// _
    }


    public void PixSize(Integer w, Integer h){
        width = w;
        height = h;
    }
    public void setMaskSize(Integer widths, Integer heights){
        maskWidth = widths;
        maskHeight = heights;
    }

    public int[] getMaskSize(){
        return new MaskSize().size;
    }

    private class MaskSize{
            private final int[] size;
            private MaskSize(){
            this.size = new int[]{maskWidth, maskHeight, width, height};
        }
    }

然后拍照保存前的最重要的一段代码:获取拍照时的图片,用原图的宽和高分别减去他们,剩下的就是矩形里面的宽高区域,之后重新Bitmap.createBitmap()图片,保存在显示到屏幕上,就是我们想要的效果了

private Bitmap cutImage(byte[] data) {
        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        Bitmap bitmap1 = Bitmap.createScaledBitmap(bitmap, 1080, 1440, true);
        int[] sizes = this.mDrawIV.getMaskSize();
        if (sizes[0] == 0 || sizes[1] == 0) {
            return bitmap1;
        } else {
            int w = bitmap1.getWidth();
            int h = bitmap1.getHeight();
            // Log.i("myLog", "bitmapWidth  " + w);
            //Log.i("myLog", "bitmapHeight  " + h);
            int x = (w - sizes[0]) / 2;
            int y = (h - sizes[1]) / 2;
            Log.i("myLog", "x " + x + " y " + y);

            //Log.i("myLog","sizes[0] "+sizes[0]+" sizes[1]"+sizes[1]);

            return Bitmap.createBitmap(bitmap1, x, y, sizes[0], sizes[1]);
        }
    }

camera2的java代码比较多,就不贴出来了,里面有比较详细的解析,放在github上面了,有兴趣的clone下来look a look,。https://github.com/Xiaohy61/myCamera2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值