使用android camera2在相机预览中显示矩形并在其中裁剪图像

时间:2017-09-04 22:43:22

标签: android image surfaceview android-camera2 textureview

我一直在尝试使用android camera2来实现像this这样的东西。

我希望在相机预览的顶部加载一个矩形,然后按一个按钮捕捉图像,然后在矩形预览中裁剪图像。我已经尝试了很多我能找到的解决方案,但大多数都使用了弃用的android hardware.camera而不是camera2。我可以用camera2和textureview找到的那些没有裁剪的代码。在上图中,我使用在photoshop中制作的图像在我的纹理视图上放置了一个叠加层。那么我应该如何在矩形范围内裁剪它?

感谢。

2 个答案:

答案 0 :(得分:1)

要添加矩形,您只需在xml布局文件中定义图像,并将其放置在预览的中心。

裁剪使用SCALAR_CROP_REGION:

  

Rect cropRect = new Rect(0,0,1755,3120);   captureRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION,cropRect);

答案 1 :(得分:0)

试试这段代码,它为我工作

<强> MainActivity.java

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

import { BrowserRouter } from 'react-router-dom'
ReactDOM.render((
  <BrowserRouter>
    <App />
  </BrowserRouter>
), document.getElementById('root'))

registerServiceWorker();

<强> activiy_main.xml

    package com.example.myapplication;
    import android.app.Activity;
    import android.content.pm.ActivityInfo;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Matrix;
    import android.hardware.Camera;
    import android.hardware.Camera.PictureCallback;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.GestureDetector;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.Button;
    import android.widget.FrameLayout;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.RelativeLayout;
    import android.widget.Toast;

    public class MainActivity extends Activity {

    private ImageSurfaceView mImageSurfaceView;
    private Camera camera;
    RelativeLayout rl,cameraLayout;
    LinearLayout saveLayout;
    private FrameLayout cameraPreviewLayout;
    private ImageView capturedImageHolder,saveImage;
    int imageL,imageT,imageW,imageH,width,height,dpsize;

    Bitmap resizedBitmap;
    Camera mCamera = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        cameraPreviewLayout = (FrameLayout)findViewById(R.id.camera_preview);
        capturedImageHolder = (ImageView)findViewById(R.id.captured_image);

        rl = findViewById(R.id.rr2);

        cameraLayout = findViewById(R.id.cameraLayout);
        saveLayout = findViewById(R.id.saveLayout);

        saveImage = findViewById(R.id.saveImage);

        width= getWindowManager().getDefaultDisplay().getWidth();
        height= getWindowManager().getDefaultDisplay().getHeight();

        camera = checkDeviceCamera();

        mImageSurfaceView = new ImageSurfaceView(MainActivity.this, camera);
        cameraPreviewLayout.addView(mImageSurfaceView);

        dpsize = (int) (getResources().getDimension(R.dimen._150sdp));
        capturedImageHolder.setX((width-dpsize)/2);
        capturedImageHolder.setY((height -dpsize)/2);

        imageL= (int) capturedImageHolder.getX();
        imageT= (int) capturedImageHolder.getY();
        capturedImageHolder.setOnTouchListener(new MoveViewTouchListener(capturedImageHolder));
        Button captureButton = (Button)findViewById(R.id.button);

        captureButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                camera.takePicture(null, null, pictureCallback);
            }
        });
    }

    private Camera checkDeviceCamera(){

        try {
            mCamera = Camera.open();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return mCamera;
    }
    public void resetCamera()
    {
        if(mCamera!=null) {
            mCamera.release();

        }
    }

    PictureCallback pictureCallback = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            Bitmap b = BitmapFactory.decodeByteArray(data, 0, data.length);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            final int REQUIRED_SIZE = 512;
            int scale = 1;
            int wd= b.getWidth();
            while (wd >=( REQUIRED_SIZE)) {
                wd= wd/2;
                scale *= 2;
            }
            options.inSampleSize = scale;
            options.inJustDecodeBounds = false;
            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,options);

            if(bitmap==null){
                Toast.makeText(MainActivity.this, "Captured image is empty", Toast.LENGTH_LONG).show();
                return;
            }
            Matrix matrix = new Matrix();
            matrix.postRotate(90);
            bitmap= Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,false);
            int bh= bitmap.getHeight();
            int bw= bitmap.getWidth();
            width= rl.getWidth();
            height= rl.getHeight();
            int l = imageL*bw/width;
            int t = imageT*bh/height;
            int w = capturedImageHolder.getWidth()*bw/width;
            int h = capturedImageHolder.getHeight()*bh/height;

            cameraPreviewLayout.setVisibility(View.GONE);
            capturedImageHolder.setVisibility(View.VISIBLE);
            resizedBitmap= Bitmap.createBitmap(bitmap,l,t,w,h);

            if(resizedBitmap!=null) {

                cameraLayout.setVisibility(View.GONE);
                saveLayout.setVisibility(View.VISIBLE);
                saveImage.setImageBitmap(resizedBitmap);
            }
        }
    };

    public class MoveViewTouchListener
            implements View.OnTouchListener
    {
        private GestureDetector mGestureDetector;
        private View mView;


        public MoveViewTouchListener(View view)
        {
            mGestureDetector = new GestureDetector(view.getContext(), mGestureListener);
            mView = view;
        }

        @Override
        public boolean onTouch(View v, MotionEvent event)
        {
            return mGestureDetector.onTouchEvent(event);
        }

        private GestureDetector.OnGestureListener mGestureListener = new GestureDetector.SimpleOnGestureListener()
        {
            private float mMotionDownX, mMotionDownY;

            @Override
            public boolean onDown(MotionEvent e)
            {
                mMotionDownX = e.getRawX() - mView.getTranslationX();
                mMotionDownY = e.getRawY() - mView.getTranslationY();
                imageL= (int) mView.getX();
                imageT= (int) mView.getY();
                Log.d("imageview"," down");
                return true;
            }

            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
            {
                mView.setTranslationX(e2.getRawX() - mMotionDownX);
                mView.setTranslationY(e2.getRawY() - mMotionDownY);
                imageL= (int) mView.getX();
                imageT= (int) mView.getY();
                if((distanceX==0)&&(distanceY==0))
                {
                    Log.d("imageview"," zoomed");
                }

                return true;
            }
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                Log.d("imageview"," tapped");
                return true;
            }

        };
    }
}

<强> ImageSurfaceView.java

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rl"
    >

    <RelativeLayout
        android:id="@+id/cameraLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:visibility="visible">

        <RelativeLayout
            android:id="@+id/rr2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:elevation="5sp"
            android:gravity="center">


            <ImageView
                android:id="@+id/captured_image"
                android:layout_width="180sp"
                android:layout_height="180sp"
                android:elevation="8sp" />

            <FrameLayout
                android:id="@+id/camera_preview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_alignParentStart="true"
                android:layout_alignParentTop="true" />


        </RelativeLayout>


        <Button
            android:gravity="center_horizontal"
            android:id="@+id/button"
            android:layout_width="50sp"
            android:layout_height="49dp"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:background="@drawable/squarecamera__camera_snap_selected"
            android:elevation="10dp" />


    </RelativeLayout>

    <LinearLayout
        android:visibility="gone"
        android:id="@+id/saveLayout"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
            <LinearLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
                <ImageView
                    android:minHeight="200sp"
                    android:minWidth="200sp"
                    android:layout_gravity="center"
                    android:id="@+id/saveImage"
                    android:layout_width="200sp"
                    android:layout_height="200sp" />

            </LinearLayout>
    </LinearLayout>
</RelativeLayout>
  1. ImageSurfaceView 适用于相机功能。
  2. MoveViewTouchListener 是用于在相机表面视图上移动方形图像的类。
  3. 裁剪操作适用于 pictureCallback ;