在 HarmonyOS 中,要调用摄像头,需要使用多媒体框架中的 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 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 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);
}
}