使用camera2构建相机应用

xingfeng_coder xingfeng_coder     2022-12-03     151

关键词:

在Andrioid 5.0之前如果要自己创建相机应用,那么需要使用android.hardware.Camera类,但是在Android 5.0中引入了android.hardware.camera2包用于替代原有的类构建相机应用。本文主要讲述利用camera2包构建应用,如果想了解在Android 5.0之前构建应用的话,可以到官网文档查看

一、android.hardware.camera2概述

在官方文档中这样写道:android.hardware.camera2包在Android设备和个人相机设备之间提供接口,替代过时的Camera类。该包将相机设备抽象成管道,输入为捕获单个一帧的请求或单个图片的请求,输出为一个捕获结果的元数据包,附带一些请求的输出图片缓存信息。请求按照顺序处理,并且可以同时发送多个请求。

二、使用步骤

1. 获取指定摄像头并设置参数

为了获得可用的相机设备,需要首先获取CameraManager对象。获取代码如下:

 CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);

每一个CameraDevices提供了一系列描述硬件设备、设置和输出参数的静态属性。这些属性通过CameraCharacteristics对象,CameraCharacteristic对象则通过CameraManager的getCameraCharacteristicis(String)方法获得。现在很多Android设备都有两个摄像头,一个前置,一个后置。下面的代码就是获取后置摄像头的代码:

CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

        try 
            for (String cameraId : cameraManager.getCameraIdList()) 

                CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);

                Integer facing = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);

                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) 
                    continue;
                

                //TODO 后置设置头

            
         catch (CameraAccessException e) 
            e.printStackTrace();
        

CameraCharacteristics的LENS_FACING参数描述的是摄像头相对于屏幕的方向,可能值为FRONT、BACK、EXTERNAL。在获取到指定摄像头后,保存对应的cameraId,该cameraId就代表了某一摄像头。
当获得了cameraId后,就调用CameraManager的openCamera方法打开指定摄像头,方法声明如下:

void openCamera (String cameraId, 
                CameraDevice.StateCallback callback, 
                Handler handler)

其中callback是相机一旦开启后使用的回调,handler是回调所使用的。如果handler为空,那么就使用当前线程的Looper。也就是说Handler取决于Callback在哪个线程中运行。其中StataCallback的声明如下:

public abstact CameraDevice.StateCallback 

        @Override
        public abstract void onOpened(@NonNull CameraDevice cameraDevice);

        @Override
        public abstract void onDisconnected(@NonNull CameraDevice cameraDevice);

        @Override
        public abstract void onError(@NonNull CameraDevice cameraDevice, int error);

一旦相机打开,就可以获得CameraDevice对象,一般在onOpened方法中创建相机会话,在onDisconnected和onError中释放相机资源。

2. 设置预览界面

为了拍照或录像,应用需要首先用一系列输出Surface装进相机捕获绘画。每一个Surface需要首先配置好恰当的尺寸和格式。Surface可以从多种方式获得,包括SurfaceView、SurfaceTexture。一般地,相机预览图片被发送到SurfaceView或TexttureView。在这里我们简单实用TextureView。SurfaceView创建预览的例子可以参考这里。实用TextureView很简单,只需要获得SurfaceTexture对象即可。SurfaceTexture用于渲染内容。在开发中我们需要设置TextureView的SurfaceTextureListener监听器,该监听器用于监听SurfaceTexture的获得、尺寸改变、更新和销毁事件。

3. 创建相机会话

在第一步中获取到CameraDevice和第二步设置了预览界面后,下面需要利用CameraDevice和预览界面创建相机会话。应用需要创建CaptureRequest对象,该对象定义了摄像头捕获一帧需要的所有参数。CaptureRequest需要列出配置好的Surface作为输出结果的Surface。一旦CaptureRequest对象创建,可以被提交给活动着的会话用于拍一张图片或多张图片。创建会话需要使用CameraDevice的createCaptureSession方法,下面是方法的声明

void createCaptureSession (List<Surface> outputs, 
                CameraCaptureSession.StateCallback callback, 
                Handler handler)

createCaptureSession方法使用提供的一系列Surface创建新的会话。callback是会话状态的回调,Handler是回调发消息所使用的,如果为null,那么使用当前线程的Looper创建Handler。CameraCaptureSession.StateCallback是一个抽象类,有两个抽象方法,onConfigured和onConfigureFailed。在onConfigured中可以处理CaptureRequest。下面是一段示例,

try 

            SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
            surfaceTexture.setDefaultBufferSize(textureView.getWidth(), textureView.getHeight());

            Surface surface = new Surface(surfaceTexture);
            priviewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            priviewRequestBuilder.addTarget(surface);

            cameraDevice.createCaptureSession(Arrays.asList(surface, imageReader.getSurface()), new CameraCaptureSession.StateCallback() 
                @Override
                public void onConfigured(CameraCaptureSession session) 

                    try 
                        if (null == cameraDevice)
                            return;

                        cameraCaptureSession = session;

                        //预览时,需要设置自动聚焦模式
                        priviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                        previewRequest = priviewRequestBuilder.build();

                        cameraCaptureSession.setRepeatingRequest(previewRequest, mCaptureCallback, mBackgroundHandler);
                     catch (CameraAccessException e) 
                        e.printStackTrace();
                    

                

                @Override
                public void onConfigureFailed(CameraCaptureSession session) 

                    Toast.makeText(MainActivity.this, "Failed", Toast.LENGTH_SHORT).show();

                
            , null);


         catch (Exception e) 
            e.printStackTrace();
        

从代码中可以看到,在会话的onConfigured方法中保存会话对象,然后创建预览的CaptureRequest对象,因为是预览,所以使用的是CameraSession的setRepeatingRequest方法。

4. 拍照

上面建立了预览状态,并且在会话创建成功后保存了会话变量,接下来的所有拍照请求都需要提交给CameraSeesion。拍摄单张图片调用capture方法,如下

   mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
                    mBackgroundHandler);

其中mCaptureCallback用于跟踪提交的CaptureRequest的处理进程。CaptureSession.CaptureCallback的定义如下:

 public static abstract class CaptureCallback 

        /**
         * This constant is used to indicate that no images were captured for
         * the request.
         *
         * @hide
         */
        public static final int NO_FRAMES_CAPTURED = -1;


        public void onCaptureStarted(@NonNull CameraCaptureSession session,
                @NonNull CaptureRequest request, long timestamp, long frameNumber) 
            // Temporary trampoline for API change transition
            onCaptureStarted(session, request, timestamp);
        

        /**
         * Temporary for API change transition
         * @hide
         */
        public void onCaptureStarted(CameraCaptureSession session,
                CaptureRequest request, long timestamp) 
            // default empty implementation
        

        /**
         * @hide
         */
        public void onCapturePartial(CameraCaptureSession session,
                CaptureRequest request, CaptureResult result) 
            // default empty implementation
        

        public void onCaptureProgressed(@NonNull CameraCaptureSession session,
                @NonNull CaptureRequest request, @NonNull CaptureResult partialResult) 
            // default empty implementation
        


        public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) 
            // default empty implementation
        


        public void onCaptureFailed(@NonNull CameraCaptureSession session,
                @NonNull CaptureRequest request, @NonNull CaptureFailure failure) 
            // default empty implementation
        

        public void onCaptureSequenceCompleted(@NonNull CameraCaptureSession session,
                int sequenceId, long frameNumber) 
            // default empty implementation
        

        public void onCaptureSequenceAborted(@NonNull CameraCaptureSession session,
                int sequenceId) 
            // default empty implementation
        

        public void onCaptureBufferLost(@NonNull CameraCaptureSession session,
                @NonNull CaptureRequest request, @NonNull Surface target, long frameNumber) 
            // default empty implementation
        
    

可以看到很多方法都是空实现。

5. 保存图片

在用camera2包中,如何保存拍摄的图片呢?这需要使用到ImageReader类,需要创建ImageReader类并设置OnImageAvailableListener接口,OnImageAvailableListener用于处理可获得图片时,我们可以在这里保存图片。还需要在创建CameraCaptureSession时,将ImageReader也作为输出Surface接受拍摄的图片。

6. 完整例子

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class MainActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback, View.OnClickListener 

    public static final String TAG = "MainActivity";


    private static final int STATE_PREVIEW = 0;
    private static final int STATE_WAITING_LOCK = 1;
    private static final int STATE_WAITING_PRECAPTURE = 2;
    private static final int STATE_WAITING_NON_PRECAPTURE = 3;
    private static final int STATE_PICTURE_TAKEN = 4;

    private int mState = STATE_PREVIEW;

    private TextureView textureView;
    private Button captureBtn;

    private CameraCaptureSession cameraCaptureSession;
    private String cameraId;
    private CameraDevice cameraDevice;

    private HandlerThread mBackgroundThread;
    private Handler mBackgroundHandler;

    private CaptureRequest.Builder priviewRequestBuilder;
    private CaptureRequest previewRequest;

    private ImageReader imageReader;
    private File file;

    private TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() 
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) 
            openCamera();
        

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) 

        

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) 
            return false;
        

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) 

        
    ;

    private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() 
        @Override
        public void onOpened(CameraDevice camera) 

            cameraDevice = camera;
            createCameraPreviewSession();

        

        @Override
        public void onDisconnected(CameraDevice camera) 

            camera.close();
            cameraDevice = null;

        

        @Override
        public void onError(CameraDevice camera, int error) 

            camera.close();
            cameraDevice = null;

        
    ;

    private CameraCaptureSession.CaptureCallback mCaptureCallback = new CameraCaptureSession.CaptureCallback() 
        @Override
        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) 

            process(result);

        

        @Override
        public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult) 

            process(partialResult);

        

        private void process(CaptureResult result) 

            switch (mState) 
                case STATE_PREVIEW: 
                    // We have nothing to do when the camera preview is working normally.
                    break;
                
                case STATE_WAITING_LOCK: 
                    Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
                    if (afState == null) 
                        captureStillPicture();
                     else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
                            CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) 
                        // CONTROL_AE_STATE can be null on some devices
                        Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                        if (aeState == null ||
                                aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) 
                            mState = STATE_PICTURE_TAKEN;
                            captureStillPicture();
                         else 
                            runPrecaptureSequence();
                        
                    
                    break;
                
                case STATE_WAITING_PRECAPTURE: 
                    // CONTROL_AE_STATE can be null on some devices
                    Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                    if (aeState == null ||
                            aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE ||
                            aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) 
                        mState = STATE_WAITING_NON_PRECAPTURE;
                    
                    break;
                
                case STATE_WAITING_NON_PRECAPTURE: 
                    // CONTROL_AE_STATE can be null on some devices
                    Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                    if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) 
                        mState = STATE_PICTURE_TAKEN;
                        captureStillPicture();
                    
                    break;
                
            

        

    ;

    private void runPrecaptureSequence() 
        try 
            // This is how to tell the camera to trigger.
            priviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
            // Tell #mCaptureCallback to wait for the precapture sequence to be set.
            mState = STATE_WAITING_PRECAPTURE;
            cameraCaptureSession.capture(priviewRequestBuilder.build(), mCaptureCallback,
                    mBackgroundHandler);
         catch (CameraAccessException e) 
            e.printStackTrace();
        
    

    private void captureStillPicture() 

        try 
            CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            builder.addTarget(imageReader.getSurface());
            builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);

            CameraCaptureSession.CaptureCallback callback = new CameraCaptureSession.CaptureCallback() 
                @Override
                public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) 

                    Toast.makeText(MainActivity.this, "Saved:" + file, Toast.LENGTH_SHORT).show();
                    unlockFocus();
                
            ;

            cameraCaptureSession.stopRepeating();
            cameraCaptureSession.capture(builder.build(), callback, null);

         catch (CameraAccessException e) 
            e.printStackTrace();
        

    

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textureView = (TextureView) findViewById(R.id.surface);
        captureBtn = (Button) findViewById(R.id.capture);
        captureBtn.setOnClickListener(this);

        file = new File(getExternalFilesDir(null), "test.jpg");

    

    @Override
    protected void onResume() 
        super.onResume();
        mBackgroundThread = new HandlerThread("camera");
        mBackgroundThread.start();
        mBackgroundHandler = new Handler(mBackgroundThread.getLooper());

        if (textureView.isAvailable()) 
            openCamera();
         else 
            textureView.setSurfaceTextureListener(mSurfaceTextureListener);
        
    

    private void openCamera() 

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) 

            ActivityCompat.requestPermissions(this, new String[]Manifest.permission.CAMERA,
                    1);
            return;
        

        //获取相机对象
        CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try 
            for (String id : cameraManager.getCameraIdList()) 

                CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(id);
                Integer facing = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) 
                    continue;
                

                cameraId = id;

                imageReader = ImageReader.newInstance(textureView.getWidth(), textureView.getHeight(), ImageFormat.JPEG, 2);
                imageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);

                break;

            
         catch (CameraAccessException e) 
            e.printStackTrace();
        

        try 
            cameraManager.openCamera(cameraId, mStateCallback, mBackgroundHandler);
         catch (CameraAccessException e) 
            e.printStackTrace();
        
    

    /**
     * 创建预览会话
     */
    private void createCameraPreviewSession() 

        try 

            SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
            surfaceTexture.setDefaultBufferSize(textureView.getWidth(), textureView.getHeight());

            Surface surface = new Surface(surfaceTexture);
            priviewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            priviewRequestBuilder.addTarget(surface);

            cameraDevice.createCaptureSession(Arrays.asList(surface, imageReader.getSurface()), new CameraCaptureSession.StateCallback() 
                @Override
                public void onConfigured(CameraCaptureSession session) 

                    try 
                        if (null == cameraDevice)
                            return;

                        cameraCaptureSession = session;

                        //预览时,需要设置自动聚焦模式
                        priviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                        previewRequest = priviewRequestBuilder.build();

                        cameraCaptureSession.setRepeatingRequest(previewRequest, mCaptureCallback, mBackgroundHandler);
                     catch (CameraAccessException e) 
                        e.printStackTrace();
                    

                

                @Override
                public void onConfigureFailed(CameraCaptureSession session) 

                    Toast.makeText(MainActivity.this, "Failed", Toast.LENGTH_SHORT).show();

                
            , null);


         catch (Exception e) 
            e.printStackTrace();
        

    


    @Override
    public void onClick(View v) 

        //拍照
        takePic();

    

    private void takePic() 

        lockFocus();
    

    //锁住焦点
    private void lockFocus() 

        try 
            priviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START);
            mState = STATE_WAITING_LOCK;
            cameraCaptureSession.capture(priviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);
         catch (CameraAccessException e) 
            e.printStackTrace();
        
    

    //解决焦点
    private void unlockFocus() 
        try 
            priviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                    CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
            cameraCaptureSession.capture(priviewRequestBuilder.build(), mCaptureCallback,
                    mBackgroundHandler);
            mState = STATE_PREVIEW;
            cameraCaptureSession.setRepeatingRequest(previewRequest, mCaptureCallback,
                    mBackgroundHandler);
         catch (CameraAccessException e) 
            e.printStackTrace();
        
    

    private ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() 
        @Override
        public void onImageAvailable(ImageReader reader) 

            //保存图片
            mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), file));

        
    ;

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) 
        if (requestCode == 1) 
            if (grantResults.length != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) 
                //TODO 不同意
            
         else 
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            openCamera();
        
    

    /**
    *保存图片
    */
    private static class ImageSaver implements Runnable 

        private Image mImage;
        private File mFile;

        public ImageSaver(Image mImage, File mFile) 
            this.mImage = mImage;
            this.mFile = mFile;
        

        @Override
        public void run() 

            ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
            byte[] bytes = new byte[buffer.remaining()];
            buffer.get(bytes);
            FileOutputStream output = null;
            try 
                output = new FileOutputStream(mFile);
                output.write(bytes);
             catch (IOException e) 
                e.printStackTrace();
             finally 
                mImage.close();
                if (null != output) 
                    try 
                        output.close();
                     catch (IOException e) 
                        e.printStackTrace();
                    
                
            

        
    

说明

上述代码示例,参考google官方示例
本文代码可以到我的Github地址查看。

只有一个带有 Camera2 和旧相机 API 的 APK

】只有一个带有Camera2和旧相机API的APK【英文标题】:OnlyoneAPKwithCamera2andoldcameraAPI【发布时间】:2017-04-2922:21:29【问题描述】:我有一个使用camera2API和旧相机版本的应用。问题是我需要使用minSdkVersion16生成单个APK,并且由于显而... 查看详情

Android 10(api 29)camera2 api回归与广角相机

】Android10(api29)camera2api回归与广角相机【英文标题】:Android10(api29)camera2apiregressionwithwide-anglecamera【发布时间】:2020-05-0511:26:57【问题描述】:我在专为GooglePixel3XL设计的相机应用中使用了camera2api。该设备有两个前置摄像头(... 查看详情

android进阶宝典--camerax与camera2的使用比对(代码片段)

...就必须要用到。传统的相机app,一般使用到Camera或者Camera2比较多,但是Google的JectPack框架中引入了CameraX组件作为官方推荐相机架构,既然推出此框架,那么一定是有它自身的优势之处在的,本文将会从CameraX和... 查看详情

调用 Camera2 API onCaptureComplete() 但相机状态仍为 CONTROL_AE_STATE_PRECAPTURE

】调用Camera2APIonCaptureComplete()但相机状态仍为CONTROL_AE_STATE_PRECAPTURE【英文标题】:Camera2APIonCaptureComplete()iscalledbutcamerastateisstillCONTROL_AE_STATE_PRECAPTURE【发布时间】:2016-01-0221:17:20【问题描述】:我正在尝试创建一个应用,该应用使... 查看详情

app使用相机camerax(代码片段)

APP使用相机Android开发者>文档>指南-选择相机库CameraXCamera2Camera(已废弃)CameraX示例应用SampleDescriptionCameraXBasicDemonstrateshowtouseCameraXAPIs.CameraXAdvancedDemonstrateshowtouseCameraXAPIswithTFLiteandothersCameraXVideoDemonstrateshowtouseCameraXVide... 查看详情

Camera2 API OIS 问题

】Camera2APIOIS问题【英文标题】:Camera2APIOISIssue【发布时间】:2021-03-0902:48:40【问题描述】:我有一台华为NovaPlus设备。我启用了带有构建道具编辑的Camera2API,几乎可以正常工作,但ois不起作用。我认为一些库需要进行一些修复... 查看详情

androidcamera2教程·第一章·概览

...考技术A从Android5.0开始,Google引入了一套全新的相机框架Camera2(android.hardware.camera2)并且废弃了旧的相机框架Camera1(android.hardware.Camera)。作为一个专门从事相机应用开发的开发者来说,这一刻我等了太久了,Camera1那寥寥无几... 查看详情

android进阶宝典--camerax与camera2的使用比对(代码片段)

...就必须要用到。传统的相机app,一般使用到Camera或者Camera2比较多,但是Google的JectPack框架中引入了CameraX组件作为官方推荐相机架构,既然推出此框架&# 查看详情

Android使用camera2复制内置视频录制质量和帧率

】Android使用camera2复制内置视频录制质量和帧率【英文标题】:Androidcopybuilt-invideorecordingqualityandframerateusingcamera2【发布时间】:2019-06-2502:10:20【问题描述】:使用camera2API获得的图像质量和帧速率与我使用相机应用手动将视频录... 查看详情

Android中Camera和Camera2的区别

】Android中Camera和Camera2的区别【英文标题】:DifferenceBetweenCameraandCamera2inAndroid【发布时间】:2017-09-1200:10:08【问题描述】:我正在构建一个类似于社交媒体的应用程序,人们可以在其中分享照片和视频,例如Instagram。这就是相机... 查看详情

Camera2 API Android min SDK [重复]

】Camera2APIAndroidminSDK[重复]【英文标题】:Camera2APIAndroidminSDK[duplicate]【发布时间】:2016-12-2821:42:26【问题描述】:您好,我正在尝试开发一个使用自定义相机的应用程序,当我尝试使用相机类时,它已被弃用,因此我使用了android... 查看详情

androidcameraapi/camera2api相机预览及滤镜贴纸等处理(代码片段)

AndroidLollipop增加了Camera2API,并将原来的CameraAPI标记为废弃了。相对原来的CameraAPI来说,Camera2是重新定义的相机API,也重构了相机API的架构。初看之下,可能会感觉Camera2使用起来比Camera要复杂,然而使用过后&#... 查看详情

Android:Camera2错误参数传递给相机服务

】Android:Camera2错误参数传递给相机服务【英文标题】:Android:Camera2Badargumentpassedtocameraservice【发布时间】:2015-12-0714:32:37【问题描述】:有人知道我做错了什么吗...我想使用SurfaceView捕获具有预览屏幕的图像。我能够在表面视图... 查看详情

android多媒体功能开发(14)——camera2框架(代码片段)

从Android5.0开始,引入了一套Camera2框架控制相机实现拍照和录像等功能,相关的类定义在android.hardware.camera2包中。原有的android.hardware包中的Camera类降级使用,因为其功能少,灵活性差,满足不了日益复杂的相... 查看详情

EGL 错误:0x3003,相机设备遇到严重错误(Camera2 Api)

】EGL错误:0x3003,相机设备遇到严重错误(Camera2Api)【英文标题】:EGLerror:0x3003,Thecameradevicehasencounteredaseriouserror(Camera2Api)【发布时间】:2019-01-0500:47:39【问题描述】:我正在编写一个应用程序控制闪光灯相机手机,我可以控制... 查看详情

横向模式下的预览方向使用 Camera2 api 顺时针旋转

】横向模式下的预览方向使用Camera2api顺时针旋转【英文标题】:PrevieworientationinlandscapemodeisrotatedclockwisewithCamera2api\'s【发布时间】:2015-09-2915:25:55【问题描述】:我使用Camera2api编写了一个相机应用程序。但是当我以横向模式打... 查看详情

使用previewview来展示相机预览

...美实现这个却并非易事。原因是,在某些特别极端情况下camera2API的使用会变得很复杂,而且在不同设备上的行为还会有所不同。还好,JetpackCameraX库的PreviewView可以帮助您解决这一问题。通过在各种Android设备上提供开发者友好、... 查看详情

支持 Android Camera Api 和 Camera2 Api 的问题

】支持AndroidCameraApi和Camera2Api的问题【英文标题】:ProblemssupportingAndroidCameraApiandCamera2Api【发布时间】:2016-02-1414:56:14【问题描述】:我正在帮助开发一个应用程序,该应用程序需要支持所有Android版本的相机使用,而不使用任何... 查看详情