在 HarmonyOS 中,要调用摄像头,需要使用多媒体框架中的 CameraKit API。使用 CameraKit API 可以让开发者轻松调用摄像头进行图像采集、预览和录制。
以下是使用 CameraKit API 调用摄像头的基本步骤:
- 检查设备是否支持 CameraKit API。
可以使用 CameraKit.IsKitAvailable() 方法来检查设备是否支持 CameraKit API。
- 获取摄像头设备并配置参数。
可以使用 CameraKit.CameraManager.GetCameras() 方法获取设备上的摄像头列表,并使用 CameraKit.CameraManager.Open() 方法打开指定的摄像头设备。然后使用 CameraKit.Camera.SetProperty() 方法设置摄像头的参数,如分辨率、曝光等级等。
- 创建预览视图和回调函数。
可以使用 CameraKit.PreviewView 类创建一个预览视图,并在回调函数中处理预览图像数据。
- 开始预览和采集图像。
调用 CameraKit.Camera.StartPreview() 方法开始预览摄像头采集的图像,并使用 CameraKit.Camera.TakePhoto() 方法采集和保存图像。
- 关闭相机。
最后,调用 CameraKit.Camera.Close() 方法关闭摄像头设备。
需要注意的是,调用 CameraKit API 进行摄像头操作需要申请相应的权限,并且在使用完毕后需要及时关闭相机以释放资源。
以下是一个简单的使用 CameraKit API 调用摄像头的 demo 代码:
import ohos.aafwk.ability.AbilitySlice;
import ohos.agp.components.*;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.utils.Point;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.media.camera.device.Camera;
import ohos.media.camera.device.CameraAbility;
import ohos.media.camera.device.CameraDeviceCallback;
import ohos.media.camera.device.CameraManager;
import ohos.media.camera.device.CameraProperty;
import ohos.media.camera.params.ParameterKey;
import ohos.media.camera.params.PropertyKey;
import ohos.media.camera.params.adapter.CameraMetadataStatic;
import ohos.media.image.Image;
import ohos.media.image.ImageReceiver;
import ohos.media.image.common.ImageFormat;
import ohos.media.image.common.Size;
import ohos.multimodalinput.event.TouchEvent;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* CameraKit demo
*/
public class CameraKitDemo extends AbilitySlice {
// 全局变量
private CameraManager cameraManager;
private CameraAbility cameraAbility;
private SurfaceProvider surfaceProvider;
private PreviewView previewView;
private CameraDeviceCallback cameraDeviceCallback;
private ImageReceiver imageReceiver;
private Camera camera;
private Executor mImageExecutor;
private Executor mCameraExecutor;
private boolean isCameraOpen = false;
// 定义 InnerEvent type
private static final int EVENT_ID_CAPTURE = 0;
/**
* UI 初始化方法
*/
private void initView() {
// 创建 SurfaceProvider
surfaceProvider = new SurfaceProvider(this);
surfaceProvider.pinToZTop(true);
surfaceProvider.setTransparent(false);
surfaceProvider.setLayoutConfig(
new ComponentContainer.LayoutConfig(
ComponentContainer.LayoutConfig.MATCH_PARENT,
ComponentContainer.LayoutConfig.MATCH_PARENT
)
);
// 添加 SurfaceProvider 到界面中
addComponent(surfaceProvider);
// 创建 PreviewView
previewView = new PreviewView(this);
previewView.setLayoutConfig(
new ComponentContainer.LayoutConfig(
ComponentContainer.LayoutConfig.MATCH_PARENT,
ComponentContainer.LayoutConfig.MATCH_PARENT
)
);
// 添加 PreviewView 到 SurfaceProvider 中
surfaceProvider.getSurfaceOps().get().addCallback(new SurfaceOps.Callback() {
@Override
public void surfaceCreated(SurfaceOps surfaceOps) {
previewView.getSurfaceProvider().bindToConsumer(
surfaceOps,
true,
SurfaceProvider.BindingOptions.PRIORITY_DEFAULT,
ImageFormat.YUV_420_888
);
}
@Override
public void surfaceChanged(SurfaceOps surfaceOps, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceOps surfaceOps) {
previewView.getSurfaceProvider().unbindConsumer();
}
});
// 创建一个布局,并将 PreviewView 添加到布局中
ComponentContainer layout = new DirectionalLayout(this);
layout.addComponent(previewView);
layout.setLayoutAlignment(LayoutAlignment.CENTER);
// 将布局添加到当前界面中
setUIContent(layout);
}
/**
* 初始化相机设备
*/
private void initCamera() {
// 创建相机管理器
cameraManager = CameraManager.getInstance(this);
// 获取可用的摄像头列表
List<CameraAbility> abilities = cameraManager.getCameraAbilities();
// 选择一个摄像头(这里选择第一个)
cameraAbility = abilities.get(0);
// 创建摄像头设备回调
cameraDeviceCallback = new CameraDeviceCallback() {
@Override
public void onCameraAvailable(String s) {
isCameraOpen = true;
}
@Override
public void onCameraUnavailable(String s) {
isCameraOpen = false;
}
@Override
public void onCameraClosed(String s) {
isCameraOpen = false;
}
};
// 创建图片接收器,用于保存拍摄的图片
imageReceiver = ImageReceiver.create(new Size(640, 480), ImageFormat.JPEG, 1);
// 创建一个图片处理线程池,用于处理拍摄的图片
mImageExecutor = Executors.newSingleThreadExecutor();
// 创建一个相机操作线程池,用于执行相机操作
mCameraExecutor = Executors.newSingleThreadExecutor();
}
/**
* 配置相机预览参数并启动预览
*/
private void startCameraPreview() {
if (isCameraOpen) {
PreviewConfig.Builder previewConfigBuilder = cameraAbility.getPreviewConfigurationBuilder();// 创建相机预览配置构建器
// 设置相机预览参数
previewConfigBuilder.addSurface(previewView.getSurface());
// 获取支持的最大预览分辨率
Size maxPreviewSize = previewConfigBuilder.getSupportedSizes().get(0);
for (Size size : previewConfigBuilder.getSupportedSizes()) {
if (size.width * size.height > maxPreviewSize.width * maxPreviewSize.height) {
maxPreviewSize = size;
}
}
previewConfigBuilder.setSurfaceOccupancyPriority(1)
.setTargetResolution(maxPreviewSize);
// 获取相机对象
camera = cameraManager.getCamera(cameraAbility.getCameraId());
// 配置相机预览参数
camera.configure(previewConfigBuilder.build());
// 启动相机预览
camera.startPreview();
}
}
/**
* 调用相机拍摄照片
*/
private void capture() {
// 判断相机是否已经打开
if (!isCameraOpen) {
return;
}
// 创建一个子线程,用于执行拍照操作
Runnable runnable = new Runnable() {
@Override
public void run() {
Image image = null;
// 执行拍照操作
try {
CaptureRequest.Builder captureRequestBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureRequestBuilder.addTarget(imageReceiver.getReceptionSurface());
PropertyKey<Integer> captureMode = new PropertyKey<>(CameraMetadataStatic.CONTROL_CAPTURE_INTENT, Integer.class);
captureRequestBuilder.set(captureMode, CameraMetadataStatic.CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
captureRequestBuilder.set(ParameterKey.STILL_CAPTURE_TRIGGER, CameraMetadataStatic.STILL_CAPTURE_TRIGGER_START);
camera.triggerCapture(captureRequestBuilder.build(), null, mImageExecutor);
// 等待拍照完成
image = imageReceiver.acquireLatestImage();
} catch (Exception e) {
e.printStackTrace();
}
// 处理拍摄的图片
if (image != null) {
// TODO: 图片处理逻辑
// 处理完成后,释放图片资源
image.release();
}
}
};
// 使用 mCameraExecutor 线程池执行子线程
mCameraExecutor.execute(runnable);
}
/**
* 重写 onStart 方法,初始化界面和相机设备,并启动相机预览
*/
@Override
public void onStart(Intent intent) {
super.onStart(intent);
initView();
initCamera();
startCameraPreview();
}
/**
* 重写 onStop 方法,关闭相机设备
*/
@Override
public void onStop() {
super.onStop();
if (isCameraOpen) {
camera.close();
}
}
/**
* 重写 onTouchEvent 方法,处理触摸事件,调用拍照方法
*/
@Override
public boolean onTouchEvent(TouchEvent event) {
if (event.getAction() == TouchEvent.PRIMARY_POINT_DOWN) {
// 触摸屏幕时调用拍照方法
capture();
}
return super.onTouchEvent(event);
}
}