怎么用Android Camera实现最简单的预览框显示
发表于:2025-01-16 作者:千家信息网编辑
千家信息网最后更新 2025年01月16日,本篇内容介绍了"怎么用Android Camera实现最简单的预览框显示"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅
千家信息网最后更新 2025年01月16日怎么用Android Camera实现最简单的预览框显示
本篇内容介绍了"怎么用Android Camera实现最简单的预览框显示"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
Android要预览Camer2界面比Camera1稍微复杂一点,但是也是不难的,下面是简单的预览相关代码。
1、首先要再AndroidManifest.xml中添加权限
2、创建一个xml包含控件TextureView
比如activity_main.xml:
3、在Activity创建使用 CamaerManager
(1)使用 CamaerManager.openCamera(),传入监听openState状态
(2)在openState状态里面执行预览界面即可
(3)关闭预览框的时候释放一下对象就行
比如下面的MainActivity2.java代码:
package com.lwz.camera;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.Comparator;import java.util.List;import android.Manifest;import android.content.Context;import android.content.pm.PackageManager;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.CaptureFailure;import android.hardware.camera2.CaptureRequest;import android.hardware.camera2.CaptureResult;import android.hardware.camera2.TotalCaptureResult;import android.hardware.camera2.params.StreamConfigurationMap;import android.os.Bundle;import android.util.Log;import android.util.Size;import android.view.Surface;import android.view.TextureView;import android.view.View;import android.widget.Button;import android.widget.Toast;import androidx.annotation.NonNull;import androidx.appcompat.app.AppCompatActivity;import androidx.core.content.ContextCompat;/** * 本类使用Camera2使用简单相机 */public class MainActivity2 extends AppCompatActivity implements View.OnClickListener { private static final String TAG = "Camera2Test"; private static final int REQUEST_CAMERA_PERMISSION = 80; private TextureView mTextureView; private Button mBtnStart; private Button mBtnStop; private CameraManager mCameraManager; private CameraDevice mCameraDevice; private String mCameraId = "0"; private Size previewSize; // 用于设置预览的宽高 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e(TAG, "onCreate!"); setContentView(R.layout.activity_main); initData(); intiView(); initEvent(); } private void intiView() { mTextureView = (TextureView) findViewById(R.id.textureView); mBtnStart = (Button) findViewById(R.id.btnStart); mBtnStop = (Button) findViewById(R.id.btnStop); } private void initData() { mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); if (mCameraManager == null) { Toast.makeText(this, "获取不到CameraService对象!", Toast.LENGTH_LONG).show(); finish(); } } private void initEvent() { mBtnStart.setOnClickListener(this); mBtnStop.setOnClickListener(this); // 对预览View的状态监听 mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) { Log.i(TAG, "onSurfaceTextureAvailable width = " + width + ",height = " + height); //1、当SurefaceTexture可用的时候,设置相机参数并打开相机 initCamera(); } @Override public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) { Log.i(TAG, "onSurfaceTextureSizeChanged width = " + width + ",height = " + height); } @Override public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) { Log.i(TAG, "onSurfaceTextureDestroyed!"); return false; } @Override public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) { //正常预览的时候,会一直打印 //Log.i(TAG, "onSurfaceTextureUpdated!"); } }); } private void initCamera() { Log.i(TAG, "initCamera"); // 2.配置前置相机,获取尺寸及id getCameraIdAndPreviewSizeByFacing(CameraCharacteristics.LENS_FACING_FRONT); // 0为前置摄像头,Camera api1里面定义0为后置 // 3.打开相机 openCamera(); } /*获取cameraId及相机预览的最佳尺寸*/ private void getCameraIdAndPreviewSizeByFacing(int lensFacingFront) { Log.i(TAG, "getCameraIdAndPreviewSizeByFacing"); try { String[] cameraIdList = mCameraManager.getCameraIdList(); //如果设备节点不可用,会阻塞在这里 Log.i(TAG, "getCameraIdAndPreviewSizeByFacing cameraIdList = " + Arrays.toString(cameraIdList)); for (String cameraId : cameraIdList) { CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics(cameraId); int deviceLevel = cameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL); //硬件与api2的契合度,0-4 Log.i(TAG, "deviceLevel = " + deviceLevel); int facing = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING); if (facing != lensFacingFront) { continue; } StreamConfigurationMap streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); Size[] outputSizes = streamConfigurationMap.getOutputSizes(SurfaceTexture.class); mCameraId = cameraId; previewSize = setOptimalPreviewSize(outputSizes, mTextureView.getMeasuredWidth(), mTextureView.getMeasuredHeight()); Log.i(TAG, "最佳预览尺寸(w-h):" + previewSize.getWidth() + "-" + previewSize.getHeight() + ",相机id:" + mCameraId); } } catch (CameraAccessException e) { Log.e(TAG, "getCameraIdAndPreviewSizeByFacing error = " + e.getMessage()); } } /** * 打开相机,预览是在回调里面执行的。 */ private void openCamera() { try { // 4.权限检查 if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { requestCameraPermission(); return; } // 5.真正打开相机 Log.i(TAG, "openCamera"); mCameraManager.openCamera(mCameraId, mStateCallback, null); } catch (CameraAccessException e) { Log.e(TAG, "openCamera error = " + e.getMessage()); } } //请求相机权限 private void requestCameraPermission() { requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); } /** * 根据相机可用的预览尺寸和用户给定的TextureView的显示尺寸选择最接近的预览尺寸 */ private Size setOptimalPreviewSize(Size[] sizes, int previewViewWidth, int previewViewHeight) { ListbigEnoughSizes = new ArrayList<>(); List notBigEnoughSizes = new ArrayList<>(); for (Size size : sizes) { if (size.getWidth() >= previewViewWidth && size.getHeight() >= previewViewHeight) { bigEnoughSizes.add(size); } else { notBigEnoughSizes.add(size); } } if (bigEnoughSizes.size() > 0) { return Collections.min(bigEnoughSizes, new Comparator () { @Override public int compare(Size lhs, Size rhs) { return Long.signum((long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight()); } }); } else if (notBigEnoughSizes.size() > 0) { return Collections.max(notBigEnoughSizes, new Comparator () { @Override public int compare(Size lhs, Size rhs) { return Long.signum((long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight()); } }); } else { Log.e(TAG, "未找到合适的预览尺寸"); return sizes[0]; } } //关闭相机,释放对象 private void releaseCamera() { if (mCameraDevice != null) { mCameraDevice.close(); mCameraDevice = null; } } /** * 相机状态监听对象 */ private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice camera) { Log.i(TAG, "StateCallback! onOpened"); mCameraDevice = camera; // 打开成功,保存代表相机的CameraDevice实例 SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture(); surfaceTexture.setDefaultBufferSize(mTextureView.getWidth(), mTextureView.getHeight()); Surface surface = new Surface(surfaceTexture); ArrayList previewList = new ArrayList<>(); previewList.add(surface); try { // 6.将TextureView的surface传递给CameraDevice mCameraDevice.createCaptureSession(previewList, new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession session) { try { CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); builder.addTarget(surface); // 必须设置才能正常预览 CaptureRequest captureRequest = builder.build(); // 7.CameraCaptureSession与CaptureRequest绑定(这是最后一步,已可显示相机预览) session.setRepeatingRequest(captureRequest, mSessionCaptureCallback, null); } catch (CameraAccessException e) { Log.e(TAG, "createCaptureRequest error = " + e.getMessage()); } } @Override public void onConfigureFailed(@NonNull CameraCaptureSession session) { Log.e(TAG, "onConfigureFailed"); } }, null); } catch (CameraAccessException e) { Log.e(TAG, "createCaptureSession error = " + e.getMessage()); } } @Override public void onDisconnected(@NonNull CameraDevice camera) { Log.e(TAG, "StateCallback! onDisconnected camera.getId() = " + camera.getId()); releaseCamera(); } @Override public void onError(@NonNull CameraDevice camera, int error) { Log.e(TAG, "StateCallback camera.getId() = " + camera.getId() + " , error = " + error); releaseCamera(); } }; //预览情况回调 private CameraCaptureSession.CaptureCallback mSessionCaptureCallback = new CameraCaptureSession.CaptureCallback() { @Override public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber) { super.onCaptureStarted(session, request, timestamp, frameNumber); // 正常预览会一直刷新 //Log.i(TAG, "mSessionCaptureCallback onCaptureStarted frameNumber =" + frameNumber); } @Override public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult) { super.onCaptureProgressed(session, request, partialResult); Log.i(TAG, "mSessionCaptureCallback onCaptureProgressed request =" + request); } @Override public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) { super.onCaptureFailed(session, request, failure); Log.e(TAG, "mSessionCaptureCallback onCaptureFailed request =" + request); } @Override public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) { super.onCaptureCompleted(session, request, result); // 正常预览时会一直刷新 //Log.i(TAG, "mSessionCaptureCallback onCaptureCompleted request =" + request); } }; @Override public void onClick(View v) { switch (v.getId()) { case R.id.btnStart: Log.i(TAG, "btnStart!"); openCamera(); break; case R.id.btnStop: Log.i(TAG, "btnStop!"); releaseCamera(); break; default: } } @Override protected void onDestroy() { super.onDestroy(); releaseCamera(); }}
Camera1的使用更简单,但是Camera1新增功能会少一点。
Camaera1的简单使用:Android Camera1实现预览框显示
"怎么用Android Camera实现最简单的预览框显示"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!
相机
尺寸
对象
状态
时候
权限
监听
代码
内容
情况
更多
界面
知识
合适
复杂
实用
成功
学有所成
接下来
代表
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
我的世界手机可玩服务器
idea服务器端口号被占用
军工软件开发挣钱吗
mysql怎样改数据库名
1.浪潮服务器 浪潮服务器
数据库的构建采用什么
ntp服务器有多少误差
美国软件开发的工
穿透代理服务器
安装时连接数据库失败
广州企帮网络技术有限公司
服务器管理器怎么重新安装
数据库表间关系总图怎么画
中国dns解析服务器
云南网络安全工作
手机保护套海关数据库
黑客攻防与网络安全的区别
网络安全扫描文字纹身
皮肤软件开发原理
5g网络技术需要发射塔图片
网络安全职业ppt课件免费下载
wcf http服务器
网络安全法工作目标
网络安全基线加固新闻
铁路工程计算机网络技术
三互联网科技有限公司
安康市热源厂自动化控制软件开发
山东爱尚网络技术有限公司
昆山运营网络技术价格
软件开发 看板