RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1000672
Accepted
MaNa
MaNa
Asked:2020-07-08 23:10:58 +0000 UTC2020-07-08 23:10:58 +0000 UTC 2020-07-08 23:10:58 +0000 UTC

连接到 Android 相机

  • 772

我正在尝试在屏幕上显示来自相机的图像,我这样做:

package com.example.camwifi;

import android.graphics.Matrix;
import android.graphics.RectF;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;

import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    SurfaceView sv;
    SurfaceHolder holder;
    HolderCallback holderCallback;
    Camera camera;

    final int CAMERA_ID = 0;
    final boolean FULL_SCREEN = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);
        Log.i("MyLog","HelloWorld");
        sv = (SurfaceView) findViewById(R.id.surfaceView);
        holder = sv.getHolder();
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        holderCallback = new HolderCallback();
        holder.addCallback(holderCallback);
    }

    @Override
    protected void onResume() {
        super.onResume();
        camera = Camera.open(CAMERA_ID);
        setPreviewSize(FULL_SCREEN);

    }

    @Override
    protected void onPause() {
        super.onPause();
        if (camera != null) {
            camera.lock();
            camera.stopPreview();
            camera.release();
            camera = null;
        }
    }

    class HolderCallback implements SurfaceHolder.Callback {

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

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                                   int height) {
            camera.stopPreview();
            setCameraDisplayOrientation(CAMERA_ID);
            try {
                camera.setPreviewDisplay(holder);
                camera.startPreview();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {

        }

    }

    void setPreviewSize(boolean fullScreen) {

        // получаем размеры экрана
        Display display = getWindowManager().getDefaultDisplay();
        boolean widthIsMax = display.getWidth() > display.getHeight();

        // определяем размеры превью камеры
        Size size = camera.getParameters().getPreviewSize();

        RectF rectDisplay = new RectF();
        RectF rectPreview = new RectF();

        // RectF экрана, соотвествует размерам экрана
        rectDisplay.set(0, 0, display.getWidth(), display.getHeight());

        // RectF первью
        if (widthIsMax) {
            // превью в горизонтальной ориентации
            rectPreview.set(0, 0, size.width, size.height);
        } else {
            // превью в вертикальной ориентации
            rectPreview.set(0, 0, size.height, size.width);
        }

        Matrix matrix = new Matrix();
        // подготовка матрицы преобразования
        if (!fullScreen) {
            // если превью будет "втиснут" в экран (второй вариант из урока)
            matrix.setRectToRect(rectPreview, rectDisplay,
                    Matrix.ScaleToFit.START);
        } else {
            // если экран будет "втиснут" в превью (третий вариант из урока)
            matrix.setRectToRect(rectDisplay, rectPreview,
                    Matrix.ScaleToFit.START);
            matrix.invert(matrix);
        }
        // преобразование
        matrix.mapRect(rectPreview);

        // установка размеров surface из получившегося преобразования
        sv.getLayoutParams().height = (int) (rectPreview.bottom);
        sv.getLayoutParams().width = (int) (rectPreview.right);
    }

    void setCameraDisplayOrientation(int cameraId) {
        // определяем насколько повернут экран от нормального положения
        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result = 0;

        // получаем инфо по камере cameraId
        CameraInfo info = new CameraInfo();
        Camera.getCameraInfo(cameraId, info);

        // задняя камера
        if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
            result = ((360 - degrees) + info.orientation);
        } else
            // передняя камера
            if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
                result = ((360 - degrees) - info.orientation);
                result += 360;
            }
        result = result % 360;
        camera.setDisplayOrientation(result);
    }
}

在Android 5.1.1 的模拟器中,一切正常,但是在Android 9 的模拟器中运行时,出现错误Fail to connect to camera service并指向该行camera = Camera.open(CAMERA_ID);。为什么它在一个版本中运行良好而在另一个版本中运行良好?以及如何解决?

java
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    MaNa
    2020-07-09T16:28:41Z2020-07-09T16:28:41Z

    您需要使用 Camera2 库,这里是解决此问题的代码:

    package com.example.camwifi_api21;
    
    import android.Manifest;
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.content.pm.PackageManager;
    import android.graphics.ImageFormat;
    import android.hardware.camera2.CameraAccessException;
    import android.hardware.camera2.CameraCharacteristics;
    import android.hardware.camera2.CameraDevice;
    import android.hardware.camera2.CameraManager;
    import android.hardware.camera2.params.StreamConfigurationMap;
    import android.media.Image;
    import android.media.ImageReader;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.content.ContextCompat;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.util.Size;
    import android.view.TextureView;
    import android.view.View;
    import android.widget.Button;
    
    public class MainActivity extends AppCompatActivity {
    
        private CameraManager mCameraManager=null;
        private final int CAMERA1=0;
        private final int CAMERA2=1;
        CameraHelper[] myCameras=null;
        private Button mButtonOpenCamera1=null;
        private Button mButtonOpenCamera2=null;
        private static final int PERMISSION_REQUEST = 1;
        private TextureView mImageView=null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mImageView=(TextureView) findViewById(R.id.image_view);
            mCameraManager=(CameraManager) getSystemService(Context.CAMERA_SERVICE);
            try{
                String[] cameraList=mCameraManager.getCameraIdList();
                myCameras=new CameraHelper[cameraList.length];
                for(String cameraID:cameraList){
                    Log.i("MyLog",cameraID);
                    int id=Integer.parseInt(cameraID);
                    myCameras[id]=new CameraHelper(mCameraManager,cameraID);
                    myCameras[id].viewFormatSize(ImageFormat.JPEG);
                    myCameras[id].setTextureView(mImageView);
                }
            } catch (CameraAccessException e) {
                Log.e("MyLog",e.getMessage());
                e.printStackTrace();
            }
            mButtonOpenCamera1=(Button) findViewById(R.id.btn_open_camera1);
            mButtonOpenCamera2=(Button) findViewById(R.id.btn_open_camera2);
            mButtonOpenCamera1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(myCameras[CAMERA2].isOpen()){
                        myCameras[CAMERA2].closeCamera();
                    }
                    if(myCameras[CAMERA1]!=null){
                        if(!myCameras[CAMERA1].isOpen()){
                            if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){
                                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST);
                            }else{
                                myCameras[CAMERA1].openCamera();
                            }
                        }
                    }
                }
            });
            mButtonOpenCamera2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(myCameras[CAMERA1].isOpen()){
                        myCameras[CAMERA1].closeCamera();
                    }
                    if(myCameras[CAMERA2]!=null){
                        if(!myCameras[CAMERA2].isOpen()){
                            if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){
                                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST);
                            }else {
                                myCameras[CAMERA2].openCamera();
                            }
                        }
                    }
                }
            });
        }
    }
    
    package com.example.camwifi_api21;
    
    import android.annotation.SuppressLint;
    import android.graphics.Camera;
    import android.graphics.ImageFormat;
    import android.graphics.SurfaceTexture;
    import android.hardware.camera2.CameraAccessException;
    import android.hardware.camera2.CameraCaptureSession;
    import android.hardware.camera2.CameraCharacteristics;
    import android.hardware.camera2.CameraDevice;
    import android.hardware.camera2.CameraManager;
    import android.hardware.camera2.CaptureRequest;
    import android.hardware.camera2.params.StreamConfigurationMap;
    import android.media.Image;
    import android.media.ImageReader;
    import android.media.MediaCas;
    import android.support.annotation.NonNull;
    import android.util.Log;
    import android.util.Size;
    import android.view.Surface;
    import android.view.TextureView;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.nio.ByteBuffer;
    import java.sql.Array;
    import java.util.Arrays;
    
    public class CameraHelper {
    
        private CameraManager mCameraManager = null;
        private String mCameraID = null;
        private CameraDevice mCameraDevice = null;
        private TextureView mTextureView=null;
        private ImageReader mImageReaderYUV;
    
        private CameraDevice.StateCallback mCameraCallback = new CameraDevice.StateCallback() {
            @Override
            public void onOpened(@NonNull CameraDevice camera) {
                mCameraDevice = camera;
                createCameraPreviesSession();
                Log.i("MyLog", "Open camera with id:" + mCameraDevice.getId());
            }
    
            @Override
            public void onDisconnected(@NonNull CameraDevice camera) {
                mCameraDevice.close();
                Log.i("MyLog", "disconnect camera with id:" + mCameraDevice.getId());
                mCameraDevice = null;
            }
    
            @Override
            public void onError(@NonNull CameraDevice camera, int error) {
                Log.i("MyLog", "Error! camera id:" + camera.getId() + " error:" + error);
            }
        };
    
        private void createCameraPreviesSession(){
            SurfaceTexture texture=mTextureView.getSurfaceTexture();
            texture.setDefaultBufferSize(1920,1080);
            Surface surface=new Surface(texture);
            mImageReaderYUV=ImageReader.newInstance(1920,1080,ImageFormat.YUV_420_888,1);
            try{
                final CaptureRequest.Builder builder=mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                builder.addTarget(surface);
                mCameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
    
                    @Override
                    public void onConfigured(@NonNull CameraCaptureSession session) {
                        CameraCaptureSession mSession=session;
                        try{
                            mSession.setRepeatingRequest(builder.build(),null,null);
                        }catch (CameraAccessException e){
                            e.printStackTrace();
                        }
                    }
    
                    @Override
                    public void onConfigureFailed(@NonNull CameraCaptureSession session) {}
    
                },null);
            }catch (CameraAccessException e){
                e.printStackTrace();
            }
        }
    
        public CameraHelper(@NonNull CameraManager cameraManager, @NonNull String cameraID) {
            mCameraManager = cameraManager;
            mCameraID = cameraID;
        }
    
        public void viewFormatSize(int formatSize) {
            CameraCharacteristics cc = null;
            try {
                cc = mCameraManager.getCameraCharacteristics(mCameraID);
                StreamConfigurationMap configurationMap = cc.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                Size[] sizeJPEG = configurationMap.getOutputSizes(ImageFormat.JPEG);
                if (sizeJPEG != null) {
                    for (Size item : sizeJPEG) {
                        Log.i("MyLog", "w:" + item.getWidth() + " h:" + item.getHeight());
                    }
                } else {
                    Log.e("MyLog", "camera with id: " + mCameraID + " don't support JPEG");
                }
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }
    
        public boolean isOpen() {
            if (mCameraDevice == null) {
                return false;
            } else {
                return true;
            }
        }
    
        @SuppressLint("MissingPermission")
        public void openCamera() {
            try {
                mCameraManager.openCamera(mCameraID, mCameraCallback, null);
            }catch (CameraAccessException e){
                Log.e("MyLog",e.getMessage());
            }
        }
    
        public void closeCamera(){
            if(mCameraDevice!=null){
                mCameraDevice.close();
                mCameraDevice=null;
            }
        }
    
        public void setTextureView(TextureView textureView){
            mTextureView=textureView;
        }
    
    }
    
    • 4
  2. Спицко Дмитрий
    2020-07-09T02:01:12Z2020-07-09T02:01:12Z

    一切都很简单——相机早已被弃用。移动到相机 2

    • 3

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5