首页 > 解决方案 > 带有android的Opencv的CameraBridgeViewBase正在拍摄黑色照片

问题描述

我正在尝试在我的 CameraActivity.java 中拍照,然后通过 Intent 将其发送到 MainActivity.java。相机工作正常,可视化没有问题,但是当我按下按钮拍照时,发送到 MainActivity 的位图是全黑图像。图片也保存在我的画廊中,但为黑色图像。这是我使用的代码CameraBridgeViewBase
代码CameraActivity.java

package com.example.firstappwithopencv;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.Toast;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.JavaCameraView;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import java.io.ByteArrayOutputStream;


public class CameraActivity extends AppCompatActivity  implements CameraBridgeViewBase.CvCameraViewListener2{

    private CameraBridgeViewBase  cameraBridgeViewBase;
    //Constant for WRITE_EXTERNAL_STORAGE permission
    static final Integer WRITE_EXST = 0x3;
    //Constant for camera permission
    static final Integer CAMERA = 0x5;

    private Mat mat1, mat2, mat3;
    private ImageButton captureButton, frontCameraButton;

    private int currentOrientation;
    static {
        OpenCVLoader.initDebug();
    }
    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS:
                {
                    Log.i("CameraActivity", "OpenCV loaded successfully");
                    cameraBridgeViewBase.enableView();
                } break;
                default:
                {
                    super.onManagerConnected(status);
                } break;
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);
        //ask permission for camera
        askForPermission(Manifest.permission.CAMERA,CAMERA);
        //ask permission for RITE_EXTERNAL_STORAGE. The method getImageUri() requires it
        askForPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,WRITE_EXST);

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        OpenCVLoader.initDebug();

        cameraBridgeViewBase =(JavaCameraView)findViewById(R.id.java_camera_view);
        cameraBridgeViewBase.setVisibility(SurfaceView.VISIBLE);
        cameraBridgeViewBase.setCvCameraViewListener(this);


        captureButton = findViewById(R.id.capture_button);

        captureButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(CameraActivity.this, MainActivity.class);

                //Bitmap bitmap = Bitmap.createBitmap(mat1.width(), mat1.height(), Bitmap.Config.RGB_565);
                Bitmap bitmap = Bitmap.createBitmap(mat1.width(), mat1.height(), Bitmap.Config.ARGB_8888);
                intent.putExtra("imageUri", getImageUri(CameraActivity.this, bitmap) + "");
                startActivity(intent);
            }
        });

        frontCameraButton = findViewById(R.id.front_camera);

    }


    @Override
    public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
        mat1=inputFrame.rgba();
        return mat1;
    }

    @Override
    public void onCameraViewStopped() {
        mat1.release();
        //mat2.release();
        //mat3.release();

    }

    @Override
    public void onCameraViewStarted(int width, int height) {
        mat1 =new Mat(width,height,CvType.CV_8UC4);
        mat1 =new Mat(width,height,CvType.CV_8UC4);
        mat1 =new Mat(width,height,CvType.CV_8UC4);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if(cameraBridgeViewBase!=null){
            cameraBridgeViewBase.disableView();
        }

    }

    @Override
    protected void onResume() {
        super.onResume();
        if (OpenCVLoader.initDebug())
            mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
        else
            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION, this, mLoaderCallback);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(cameraBridgeViewBase!=null){
            cameraBridgeViewBase.disableView();
        }
    }

    public Uri getImageUri(Context inContext, Bitmap inImage) {

        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        inImage.compress(Bitmap.CompressFormat.PNG, 100, bytes);
        String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
        return Uri.parse(path);
    }


    private void askForPermission(String permission, Integer requestCode) {
        if (ContextCompat.checkSelfPermission(CameraActivity.this, permission) != PackageManager.PERMISSION_GRANTED) {
            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(CameraActivity.this, permission)) {
                //This is called if user has denied the permission before
                //In this case I am just asking the permission again
                ActivityCompat.requestPermissions(CameraActivity.this, new String[]{permission}, requestCode);
            } else {
                ActivityCompat.requestPermissions(CameraActivity.this, new String[]{permission}, requestCode);
            }
        } else {
            Toast.makeText(this, "" + permission + "the permission is ready!", Toast.LENGTH_SHORT).show();
        }
    }


}

这是onCreate()my 方法的代码MainActivity.java

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        imgInput = findViewById(R.id.imgInput);

        //Receive bitmap that is sent from the CameraActivity activity
        Bundle extras = getIntent().getExtras();
        if(extras!=null){
            Uri imageUri = Uri.parse(extras.getString("imageUri"));
            try{
                imageBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
                //Put the bitmap into ImageView imgInput
                imgInput.setImageBitmap(imageBitmap);
            }catch (IOException e){
                e.printStackTrace();
            }
        }

    }

我在两个不同的应用程序中测试了 mycode,一个使用 opencv 3.4.7,另一个使用 opencv 3.4.10。我认为问题出在以下方法中CameraActivity.java

public Uri getImageUri(Context inContext, Bitmap inImage) {

    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.PNG, 100, bytes);
    String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
    return Uri.parse(path);
}

正在保存黑色图像?
此外,我在考虑onClick()拍摄照片并通过 Intent 发送的按钮方法内部存在问题:

captureButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(CameraActivity.this, MainActivity.class);

                Bitmap bitmap = Bitmap.createBitmap(mat1.width(), mat1.height(), Bitmap.Config.ARGB_8888);
                intent.putExtra("imageUri", getImageUri(CameraActivity.this, bitmap) + "");
                startActivity(intent);
            }
        });

我也这样做了:

Bitmap bitmap = Bitmap.createBitmap(mat1.width(), mat1.height(), Bitmap.Config.RGB_565);

但结果是发送全黑图像。


我的相机工作正常,我的权限没有问题。好吧,伙计们,如果您有任何想法或建议,我将不胜感激。非常感谢。

标签: javaandroidopencvandroid-camera

解决方案


推荐阅读