自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用Camera2,讓相機功能更靈活

移動開發(fā) 移動應用
使用Camera2 API,開發(fā)者可以實現(xiàn)更多的相機功能,如手動對焦、手動曝光、原生RAW圖像捕獲等。同時,Camera2 API也提供了更好的性能和更低的延遲,使得相機應用在性能要求較高的場景下能夠更好地發(fā)揮作用。

Camera2介紹

Camera2 API是Android系統(tǒng)中用于訪問相機功能的一套API。它提供了更強大和靈活的相機控制能力,相比之前的Camera API,Camera2 API支持更多的功能和更高的性能。

使用Camera2 API,開發(fā)者可以實現(xiàn)更多的相機功能,如手動對焦、手動曝光、原生RAW圖像捕獲等。同時,Camera2 API也提供了更好的性能和更低的延遲,使得相機應用在性能要求較高的場景下能夠更好地發(fā)揮作用。

在Android系統(tǒng)中,相機功能的實現(xiàn)離不開Camera2 API的支持,因此對于需要使用相機功能的應用開發(fā)者來說,熟悉并掌握Camera2 API是非常重要的。

Camera2主要包括以下幾個重要組件:

  1. CameraManager:相機管理器,用于檢測和連接可用的相機設備。
  2. CameraDevice:相機設備,代表一個物理相機設備,可以打開、配置和關(guān)閉相機設備。
  3. CameraCaptureSession:相機捕獲會話,用于發(fā)送捕獲請求和接收捕獲結(jié)果,可以預覽、拍照、錄像等。
  4. CameraCharacteristics:相機特性,提供了相機設備的靜態(tài)信息,如支持的參數(shù)、分辨率、對焦模式等。

使用Camera2,開發(fā)者可以更靈活地控制相機的功能和參數(shù),實現(xiàn)更豐富的相機應用程序。

Camera2使用

  1. 檢查相機權(quán)限:確保在AndroidManifest.xml文件中添加了相機權(quán)限
<uses-permission android:name="android.permission.CAMERA" />
  1. 設置相機預覽
  • 創(chuàng)建一個TextureView用于顯示相機預覽畫面。
  • 使用CameraManager獲取相機設備的ID,并打開相機。
  • 創(chuàng)建CameraCaptureSession用于預覽。
  1. 拍照
  • 創(chuàng)建一個按鈕用于觸發(fā)拍照操作。
  • 當用戶點擊按鈕時,使用CameraCaptureSession進行拍照操作。
  • 保存拍攝的照片到指定的文件路徑。
  1. 處理相機權(quán)限和生命周期
  • 在onResume方法中檢查相機權(quán)限,并打開相機。
  • 在onPause方法中關(guān)閉相機,釋放相關(guān)資源。

示例代碼:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextureView
        android:id="@+id/textureView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

    <Button
        android:onClick="takePicture"
        android:id="@+id/btnCapture" 
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="拍照"/>
</LinearLayout>
public class CameraActivity extends AppCompatActivity {

    private static final int REQUEST_CAMERA_PERMISSION = 200;
    private static final int REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION = 201;

    private CameraManager cameraManager;
    private String cameraId;
    private CameraDevice cameraDevice;
    private CameraCaptureSession cameraCaptureSession;
    private CaptureRequest.Builder captureRequestBuilder;
    private ImageReader imageReader;

    private TextureView textureView;

    private final TextureView.SurfaceTextureListener surfaceTextureListener = 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 final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(@NonNull CameraDevice camera) {
            cameraDevice = camera;
            createCameraPreview();
        }

        @Override
        public void onDisconnected(@NonNull CameraDevice camera) {
            cameraDevice.close();
        }

        @Override
        public void onError(@NonNull CameraDevice camera, int error) {
            cameraDevice.close();
            cameraDevice = null;
        }
    };

    private final CameraCaptureSession.StateCallback captureSessionStateCallback = new CameraCaptureSession.StateCallback() {
        @Override
        public void onConfigured(@NonNull CameraCaptureSession session) {
            cameraCaptureSession = session;
            try {
                captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                cameraCaptureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onConfigureFailed(@NonNull CameraCaptureSession session) {
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);

        textureView = findViewById(R.id.textureView);
        
        textureView.setSurfaceTextureListener(surfaceTextureListener);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (textureView.isAvailable()) {
            openCamera();
        } else {
            textureView.setSurfaceTextureListener(surfaceTextureListener);
        }
    }

    @Override
    protected void onPause() {
        closeCamera();
        super.onPause();
    }

    private void openCamera() {
        cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            cameraId = cameraManager.getCameraIdList()[0];
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
                return;
            }
            cameraManager.openCamera(cameraId, stateCallback, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    private void createCameraPreview() {
        SurfaceTexture texture = textureView.getSurfaceTexture();
        texture.setDefaultBufferSize(textureView.getWidth(), textureView.getHeight());
        Surface surface = new Surface(texture);
        try {
            captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            captureRequestBuilder.addTarget(surface);
            cameraDevice.createCaptureSession(Collections.singletonList(surface), captureSessionStateCallback, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    private void closeCamera() {
        if (cameraCaptureSession != null) {
            cameraCaptureSession.close();
            cameraCaptureSession = null;
        }
        if (cameraDevice != null) {
            cameraDevice.close();
            cameraDevice = null;
        }
    }

    public void takePicture() {
        if (cameraDevice == null) {
            return;
        }
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
            Size[] jpegSizes = null;
            if (characteristics != null) {
                jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
            }
            int width = 640;
            int height = 480;
            if (jpegSizes != null && jpegSizes.length > 0) {
                width = jpegSizes[0].getWidth();
                height = jpegSizes[0].getHeight();
            }
            ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
            List<Surface> outputSurfaces = new ArrayList<>(2);
            outputSurfaces.add(reader.getSurface());
            outputSurfaces.add(new Surface(textureView.getSurfaceTexture()));

            CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            captureBuilder.addTarget(reader.getSurface());
            captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);

            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));

            File file = new File(getExternalFilesDir(null), "pic.jpg");
            ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
                @Override
                public void onImageAvailable(ImageReader reader) {
                    Image image = null;
                    try {
                        image = reader.acquireLatestImage();
                        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                        byte[] bytes = new byte[buffer.capacity()];
                        buffer.get(bytes);
                        save(bytes);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        if (image != null) {
                            image.close();
                        }
                    }
                }

                private void save(byte[] bytes) throws IOException {
                    OutputStream output = null;
                    try {
                        output = new FileOutputStream(file);
                        output.write(bytes);
                    } finally {
                        if (output != null) {
                            output.close();
                        }
                    }
                }
            };

            reader.setOnImageAvailableListener(readerListener, null);

            final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
                @Override
                public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                    super.onCaptureCompleted(session, request, result);
                    Toast.makeText(CameraActivity.this, "Saved:" + file, Toast.LENGTH_SHORT).show();
                    createCameraPreview();
                }
            };

            cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession session) {
                    try {
                        session.capture(captureBuilder.build(), captureListener, null);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                }
            }, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }
}

在這個示例中,我們首先需要獲取相機權(quán)限和存儲權(quán)限,然后通過CameraManager打開相機,創(chuàng)建預覽界面,并實現(xiàn)拍照功能。在拍照時,我們需要設置圖片的大小、旋轉(zhuǎn)角度等參數(shù),并保存拍攝的照片。

Camera2優(yōu)缺點

優(yōu)點

  1. 「全面的控制」:Camera2 API提供了更多的相機控制,包括手動對焦、曝光、白平衡等功能,使得開發(fā)者可以更精細地控制相機的行為。
  2. 「性能優(yōu)化」:Camera2 API在性能上進行了優(yōu)化,能夠更好地利用多核處理器和硬件加速功能,提高相機應用的運行效率。
  3. 「支持原生RAW格式」:Camera2 API支持原生的RAW圖像捕獲,使得攝影愛好者和專業(yè)攝影師可以更好地處理和編輯照片。

缺點

  1. 「復雜性」:相比于之前的Camera API,Camera2 API的使用復雜度更高,需要開發(fā)者具備更多的相機知識和經(jīng)驗。
  2. 「兼容性問題」:部分老舊的設備可能不支持Camera2 API,這會導致應用在這些設備上無法正常運行。
  3. 「學習曲線」:對于新手開發(fā)者來說,學習并掌握Camera2 API可能需要花費更多的時間和精力。
責任編輯:武曉燕 來源: 沐雨花飛蝶
相關(guān)推薦

2021-11-01 17:31:21

Camera2 相機開發(fā)

2009-05-18 09:12:00

ASON自動交換光網(wǎng)絡

2023-06-06 19:24:06

KubernetesSpark

2023-12-05 10:25:24

Python類型注解

2024-11-21 15:48:40

2011-02-23 09:48:00

Python.NET

2011-02-22 10:00:38

.NETc#IronPython

2009-06-03 09:08:20

ScalaJava類型

2023-12-01 16:00:48

Python結(jié)構(gòu)化模式

2013-06-13 17:30:16

Camera360拍照軟件

2017-07-18 06:08:41

2015-05-04 14:12:43

2015-12-04 10:25:50

VR拍照谷歌

2018-10-26 15:26:06

華為云

2023-02-13 15:54:49

2020-09-14 09:33:02

網(wǎng)絡

2025-02-18 00:10:00

2011-09-28 13:28:56

F5虛擬化云計算

2020-10-28 15:17:08

Go服務超時net

2019-04-04 14:05:20

consolejs前端
點贊
收藏

51CTO技術(shù)棧公眾號