android 相机预览 宽度和高度,Android实现Camera2预览和拍照效果

本文介绍了如何使用Android Camera2 API实现相机预览和拍照功能,包括连接到设备的相机、设置预览显示、创建CameraCaptureSession、处理焦点锁定和拍照流程。提供了一个简单的CameraPreview类的实现,该类继承自TextureView,并包含了相机预览、拍照和焦点管理的详细步骤。
摘要由CSDN通过智能技术生成

简介

网上对于 Camera2 的介绍有很多,在 Github 上也有很多关于 Camera2 的封装库,但是对于那些库,封装性太强,有时候我们仅仅是需要个简简单单的拍照功能而已,因此,自定义一个 Camera 使之变得轻量级那是非常重要的了。(本文并非重复造轮子, 而是在于学习 Camera2API 的基本功能, 笔记之。)

学习要点:

使用 Android Camera2 API 的基本功能。

迭代连接到设备的所有相机的特征。

显示相机预览和拍摄照片。

Camera2 API 为连接到 Android 设备的各个相机设备提供了一个界面。 它替代了已弃用的 Camera 类。

使用 getCameraIdList 获取所有可用摄像机的列表。 然后,您可以使用 getCameraCharacteristics,并找到适合您需要的最佳相机(前 / 后面,分辨率等)。

创建一个 CameraDevice.StateCallback 的实例并打开相机。 当相机打开时,准备开始相机预览。

使用 TextureView 显示相机预览。 创建一个 CameraCaptureSession 并设置一个重复的 CaptureRequest。

静像拍摄需要几个步骤。 首先,需要通过更新相机预览的 CaptureRequest 来锁定相机的焦点。

然后,以类似的方式,需要运行一个预捕获序列。之后,它准备拍摄一张照片。 创建一个新的 CaptureRequest 并调用 [capture] 。

完成后,别忘了解锁焦点。

实现效果

64ceffb161d9a401585bfc69a3208464.png环境

SDK>21

Camera2 类图

ebed334292335920f2ee398ebe51988c.png

0457893e3b2938331fa045baeb4620f7.png

代码实现

CameraPreview.java

/**

* Created by shenhua on 2017-10-20-0020.

* Email shenhuanet@126.com

*/

public class CameraPreview extends TextureView {

private static final String TAG = "CameraPreview";

private static final SparseIntArray ORIENTATIONS = new SparseIntArray();//从屏幕旋转转换为JPEG方向

private static final int MAX_PREVIEW_WIDTH = 1920;//Camera2 API 保证的最大预览宽高

private static final int MAX_PREVIEW_HEIGHT = 1080;

private static final int STATE_PREVIEW = 0;//显示相机预览

private static final int STATE_WAITING_LOCK = 1;//焦点锁定中

private static final int STATE_WAITING_PRE_CAPTURE = 2;//拍照中

private static final int STATE_WAITING_NON_PRE_CAPTURE = 3;//其它状态

private static final int STATE_PICTURE_TAKEN = 4;//拍照完毕

private int mState = STATE_PREVIEW;

private int mRatioWidth = 0, mRatioHeight = 0;

private int mSensorOrientation;

private boolean mFlashSupported;

private Semaphore mCameraOpenCloseLock = new Semaphore(1);//使用信号量 Semaphore 进行多线程任务调度

private Activity activity;

private File mFile;

private HandlerThread mBackgroundThread;

private Handler mBackgroundHandler;

private Size mPreviewSize;

private String mCameraId;

private CameraDevice mCameraDevice;

private CaptureRequest.Builder mPreviewRequestBuilder;

private CaptureRequest mPreviewRequest;

private CameraCaptureSession mCaptureSession;

private ImageReader mImageReader;

static {

ORIENTATIONS.append(Surface.ROTATION_0, 90);

ORIENTATIONS.append(Surface.ROTATION_90, 0);

ORIENTATIONS.append(Surface.ROTATION_180, 270);

ORIENTATIONS.append(Surface.ROTATION_270, 180);

}

public CameraPreview(Context context) {

this(context, null);

}

public CameraPreview(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public CameraPreview(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

mFile = new File(getContext().getExternalFilesDir(null), "pic.jpg");

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int width = MeasureSpec.getSize(widthMeasureSpec);

int height = MeasureSpec.getSize(heightMeasureSpec);

if (0 == mRatioWidth || 0 == mRatioHeight) {

setMeasuredDimension(width, height);

} else {

if (width < height * mRatioWidth / mRatioHeight) {

setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);

} else {

setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);

}

}

}

public void onResume(Activity activity) {

this.activity = activity;

startBackgroundThread();

//当Activity或Fragment OnResume()时,可以冲洗打开一个相机并开始预览,否则,这个Surface已经准备就绪

if (this.isAvailable()) {

openCamera(this.getWidth(), this.getHeight());

} else {

this.setSurfaceTextureListener(mSurfaceTextureListener);

}

}

public void onPause() {

closeCamera();

stopBackgroundThread();

}

public void setOutPutDir(File file) {

this.mFile = file;

}

public void setAspectRatio(int width, int height) {

if (width < 0 || height < 0) {

throw new IllegalArgumentException("Size can't be negative");

}

mRatioWidth = width;

mRatioHeight = height;

requestLayout();

}

public void setAutoFlash(CaptureRequest.Builder requestBuilder) {

if (mFlashSupported) {

requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,

CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);

}

}

public void takePicture() {

lockFocus();

}

private void startBackgroundThread() {

mBackgroundThread = new HandlerThread("

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值