Показать прямоугольник в предварительном просмотре камеры и обрезать изображение внутри него с помощью камеры android2

Я пытался добиться чего-то вроде this с помощью камеры android2.

Я хочу, чтобы прямоугольник загружался поверх предварительного просмотра моей камеры, и как только я нажимаю кнопку для захвата изображения, изображение должно быть обрезано в предварительном просмотре прямоугольника. Я пробовал множество решений, которые смог найти, но в большинстве из них используется устаревшее оборудование android. Camera, а не camera2. Те, которые я смог найти с помощью camera2 и textureview, не имеют кода для обрезки. На изображении выше я наложил оверлей на вид текстуры, используя изображение, которое я сделал в фотошопе. Итак, как мне обрезать его только в пределах прямоугольника?

Спасибо.


person mxs2649    schedule 04.09.2017    source источник
comment
Есть какое-нибудь решение?   -  person Upendra    schedule 24.09.2018
comment
Неа. В конце концов, я отказался от этого.   -  person mxs2649    schedule 24.09.2018


Ответы (2)


Чтобы добавить прямоугольник, вы можете просто определить изображение в файле макета xml и расположить его в центре предварительного просмотра.

Обрезка использует SCALAR_CROP_REGION:

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

person Mick    schedule 13.09.2017
comment
Отлично работает! Обрезает прямоугольную область на самом снимке. Сэкономлено много времени. Спасибо - person sam; 26.03.2019

Попробуйте этот код, он работает для меня

MainActivity.java

    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;
            }

        };
    }
}

activiy_main.xml

<?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>

ImageSurfaceView.java

    package com.example.myapplication;

    import android.content.Context;
    import android.hardware.Camera;
    import android.util.Log;
    import android.view.Display;
    import android.view.Surface;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.WindowManager;

    import java.io.IOException;

    import static android.content.Context.WINDOW_SERVICE;

    public class ImageSurfaceView extends SurfaceView implements SurfaceHolder.Callback {

    private Camera mCamera;
    private SurfaceHolder surfaceHolder;
    Context context;
    boolean isPreviewRunning = false;

    public ImageSurfaceView(Context context, Camera camera) {
        super(context);
        this.mCamera = camera;
        this.context = context;
        this.surfaceHolder = getHolder();
        this.surfaceHolder.addCallback(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            this.mCamera.setPreviewDisplay(holder);
            this.mCamera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (isPreviewRunning) {
            mCamera.stopPreview();
        }

        Display display = ((WindowManager)context.getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

        if(display.getRotation() == Surface.ROTATION_0) {
            mCamera.setDisplayOrientation(90);
        }

        if(display.getRotation() == Surface.ROTATION_90) {
        }

        if(display.getRotation() == Surface.ROTATION_180) {
        }

        if(display.getRotation() == Surface.ROTATION_270) {

            mCamera.setDisplayOrientation(180);
        }

        previewCamera();
    }


    public void previewCamera() {
        try {
            mCamera.setPreviewDisplay(surfaceHolder);
            mCamera.startPreview();
            isPreviewRunning = true;
        } catch(Exception e) {
            Log.d("hsfhj", "Cannot start preview", e);
        }
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        this.mCamera.stopPreview();
        this.mCamera.release();
    }
}
  1. ImageSurfaceView предназначен для функций камеры.
  2. MoveViewTouchListener - это класс для перемещения квадратного изображения по поверхности камеры.
  3. Действие обрезки работает внутри pictureCallback;
person Athira    schedule 18.06.2018
comment
Вы можете поделиться squarecamera__camera_snap_selected - person Mehroze Yaqoob; 12.07.2018
comment
Вы можете использовать круглое изображение как squarecamera__camera_snap_selected - person Athira; 13.10.2018
comment
Привет, много чего не хватает getResources (). GetDimension (R.dimen._150sdp) какое значение? и я ничего не вижу на экране, вид с камеры - person pritam001; 13.05.2019
comment
Это значения размеров. измените его на 150dp. Используйте любой значок для захвата - person Athira; 13.05.2019
comment
в вопросе указано camera2, но ваше решение предназначено для старого api: - person Systemsplanet; 16.05.2019